zoukankan      html  css  js  c++  java
  • JAVA-初步认识-第十三章-死锁示例

    一.

    接下来将的也是同步的一个小知识点,我们在使用同步的时候,会有这么一种现象,死锁。

    什么情况下,是锁死?在我们程序当中,最常见的体现形式之一就是同步的嵌套。形象的说法是:两个人各有一只筷子,都想要吃饭,结果争执之下,谁都吃不了。和谐的情况就是,筷子给对方,对方吃饭之后,再连自己的筷子一起还回来,我们再吃饭。

    和谐的情况有,相持不下的情况也有。这种相持的情况就是死锁,现在通过一个程序来验证一下。

    死锁的一种体现形式之一,就是同步嵌套。

     现在是同步函数中包含由同步代码块,同步代码块中包含着同步函数,同步函数的锁是this,同步代码块的锁是obj。

    (这里我的疑问是两个同步代码块是同一个么?同步函数肯定是同一个)

     

    流程是这样的,一个线程进来,先执行同步代码块,先拿obj锁,拿完锁就进来了。一进来又多了一个同步,这同步是同步函数,锁是this。这就是两锁,obj里面有个this。接着往下看,一个线程在读同步函数的时候,先拿this,this里面有谁,obj吧。这就是两个锁在嵌套。

    接着就执行一下,

    DOS结果显示直接卡在那儿了。再多次编译运行,还有全部交替输出的,那就是和谐的。

    甚至还有直接挂掉的。

    主线程睡10毫秒时,0线程就拿到了cpu执行权,当主线程醒了之后,就继续执行t.flag=false; t2.start();

    当0线程得到执行权时,冲进来拿到同步代码块的obj锁,紧接着到show方法里拿this锁,然后读show函数,接着又进入同步代码块,读里面的内容,if里面的语句读了三句,100~98。紧跟着t2这个线程也要准备要读了,(它是按false进入的),是读else。这个0线程有可能出了object了,还没等出这show呢,t2线程就拿到了show所带有的this锁。它一拿到this锁,就进入show函数,而0线程拿着this,(也就是说0线程拿着在同步代码块的声明那,拿着obj想要进调用show函数的this,而1线程在show函数声明那,拿着this,想要进同步代码块拿obj),互相都不放,且都拿着自己的锁,谁都不放,谁都进不去,这种就是死锁。→我觉着这个争夺和执行权在谁手里有什么必要联系么?我是说,没有cpu执行权也能握有锁不放

    如果一个线程拿到锁,又出去了,全释放了。第二个线程接着进来,这就比较和谐了。

    这是为了告诉大家,尽量不要设成死锁,这样问题不好解决。

    二.

    现在给大家介绍一个死锁程序,面试多线程的时候会碰到,请给我写个死锁程序。

    写一个简单点的死锁程序。(遵循原则就一个嵌套)

    标记是锁的意思么?

    本例中两个嵌套的是同步代码块,(为什么不采用同步函数呢?),同时为这个两个同步代码块制备两个锁。

    MyLock类中,对象locka前面的修饰符final是什么意思?

    感觉上面的MyLock类中的定义挺奇怪的,到底是函数还是变量?由于是锁,肯定是函数,但是为什么这么写?

    突然想到锁,或者同步,感觉逻辑很差,视频在讲解的时候,很多时候是自己构建了特点的环境。有没有对于同步更确切的描述呢

    以前说线程任务的时候,是一个对象(多个线程操作同一个任务),这里为什么new了两个线程任务呢?

     两个线程执行路径,只能是两个任务,但是这并不影响我去演示,为什么呢?我们这两个线程运行的都是run方法,而这flag,虽然我这两个对象都有自己的flag,但是它们的值也是固定的,一个是true,另一个是false。

    只有这种情况发生多个任务无所谓,因为你执行要么是true,要么是false,只有这两种情况。

    我这线程任务里封装的资源是boolean型变量,虽然这个变量在两个任务对象当中都有独立的一份,但是取得值只能是两个,要么是真,要么是假。如果这里写的不是flag,而是num,int num=100,那就废了,这会导致两个线程任务执行的是两个100。

    我们也可以不调用构造函数,那就要先给flag一个值,先满足一个值,然后再切换。

    现在设想的这个程序能够锁上么?

    从DOS结果看,就是锁住了,一个线程拿到了locka的锁,输出了“if  locka.....”,但是没拿到lockb锁,因此进不来下一步。而另一个线程拿到了lockb锁,输出了“if  lockb.....”,但是没有locka锁。最终的结果就是另个输出语句。

    也可以将线程的名称输出,

    DOS结果也显示的死锁。但是相同的这个程序换个cpu来执行,也许就和谐了。因此为了更大概率的出现我们需要展示的死锁线程,我们设置循环语句,执行的次数增加,自然出现死锁的概率就变大了。

    前面书写的while(true),可能是一直循环,在后台打印时强制停止。

    DOS结果显示,有锁死也有和谐,而且我们刚才说的while(true)可能就是意味着多次循环。

  • 相关阅读:
    C# 上传辅助方法
    C# 经纬度计算
    C#Excel导出反射数据集
    C# 数据模板导出
    C# 百度经纬度获取地址信息
    【平台开发】— 5.后端:代码分层
    【平台开发】— 4.mysql建库建表
    【平台开发】— 3.前端开发思路
    【平台开发】— 2.前端:vue-element-admin
    【平台开发】— 1.开篇
  • 原文地址:https://www.cnblogs.com/wsw-bk/p/8045070.html
Copyright © 2011-2022 走看看