文档章节

Java:多线程死锁

alexwan
 alexwan
发布于 2015/01/29 10:38
字数 938
阅读 200
收藏 6

    死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。

    产生死锁的原因:

    1.因为系统资源不足。

    2.进程运行推进的顺序不合适。    

    3.资源分配不当。

    产生死锁的条件:

  1. 互斥条件:所谓互斥就是进程在某一时间内独占资源。

  2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

  3. 不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。

  4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

    简单的来说:死锁就是因为多线程在访问对象的时候,A线程占用了对象object1,又想去占用对象object2,但是此时的object2对象已经被B线程占用,并且B线程又想去占用object2。两个线程同时占用对方想要的对象,但是又不释放自己占有的对象,两个线程互相等待,造成拥塞无法执行下去。

    

public class LockDemo implements Runnable
{
    private static Object object1 = new Object();
    
    private static Object object2 = new Object();
    
    private int flag = 0;
    
    public static void main(String[] args)
    {
        LockDemo run0 = new LockDemo();
        LockDemo run1 = new LockDemo();
        run0.flag = 1;
        run1.flag = 2;
        Thread thread1 = new Thread(run0);
        Thread thread2 = new Thread(run1);
        thread1.start();
        thread2.start();
    }
    
    @Override
    public void run()
    {
        System.out.println(flag);
        if (flag == 1)
        {
            synchronized (object1)
            {
                System.out.println("线程 : " + flag + "锁定obj1,休息0.5秒后锁定obj2去!");
                try
                {
                    Thread.sleep(500);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                synchronized (object2)
                {
                    System.out.println("线程 : " + flag + "访问 object2");
                }
            }
        }
        if (flag == 2)
        {
            synchronized (object2)
            {
                System.out.println("线程 : " + flag + "锁定obj2,休息0.5秒后锁定obj1去!");
                try
                {
                    Thread.sleep(500);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                synchronized (object1)
                {
                    System.out.println("线程 : " + flag + "访问object1");
                }
            }
        }
        
    }
    
}

执行结果

1
2
线程 : 2锁定obj2,休息0.5秒后锁定obj1去!
线程 : 1锁定obj1,休息0.5秒后锁定obj2去!

    从执行的结果我们发现,每个线程都没有执行

System.out.println("线程 : " + flag + "访问object");

    因为线程1执行代码时把object1的时候加锁,然后去访问object2,但是此时的object2已经被线程2加上了锁,线程1和线程2分别占用object1和object2,又想去访问对方的占用的对象,显然是不可行的。就好比两个小孩交换玩具,一个小孩说:你先把玩具给我,我再把玩具给你,另外一个小孩说:不行,你要先把你的玩具给我,我再给你。结果两个小孩谁也不愿给谁,自然而然地在那僵持着。

    在代码中在修饰object对象的时候,使用了static关键字,如果不使用static 关键字的执行结果是什么样的呢?

1
线程 : 1锁定obj1,休息0.5秒后锁定obj2去!
2
线程 : 2锁定obj2,休息0.5秒后锁定obj1去!
线程 : 2访问object1
线程 : 1访问 object2

    可以看到并没有发生死锁,为什么?是因为使用static 关键字的时,两个object是公共的,不使用关键字时,两个object是线程自己用了两个独立的对象。同样我们打个比方,使用static关键修饰的object对象,就好比幼儿园中共有的两个玩具,大家谁都可以玩,但是每个小孩,都只能同时拥有一个。一个小朋友要是想要玩另外一个小朋友的玩具,必须要俩人互相交换。不用static关键字修饰的object对象,就好比每个小朋友自己带玩具来玩,不是共有的,我想玩哪个就玩哪个。

© 著作权归作者所有

alexwan
粉丝 3
博文 16
码字总数 14120
作品 0
香港
架构师
私信 提问
使用JDK自带的工具jstack找出造成运行程序死锁的原因

Java多线程编程也是Java面试中经常考察的内容。刚接触Java多线程编程的朋友们,可能会不慎写出一些会导致死锁(deadlock)的应用出来。如何分析造成Java多线程的原因呢?很多时候我们在怀疑造成...

全部原谅
2018/08/28
2
0
15个顶级Java多线程面试题及回答

Java 线程面试问题 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分。如果你想获得任何股票投资银行的前台资讯职位,那么你应该准备很多关于多线程的问题。在投资银行业务中多...

LCZ777
2014/05/27
645
0
java中高级大公司多线程面试题

1)在Java中Lock接口比synchronized块的优势是什么?你需要实现一个高效的缓存,它允许多个用户读,但只允许一个用户写,以此来保持它的完整性,你会怎样去实现它? lock接口在多线程和并发编...

java成功之路
2018/10/30
0
0
Java面试:投行的15个多线程和并发面试题

本文由ImportNew -一杯哈希不加盐 翻译自dzone。欢迎加入翻译小组。转载请见文末要求。 多线程和并发问题已成为各种 Java 面试中必不可少的一部分。如果你准备参加投行的 Java 开发岗位面试,...

ImportNew
2018/08/23
0
0
【转】15个顶级Java多线程面试题及回答

Java 线程面试问题   在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分。如果你想获得任何股票投资银行的前台资讯职位,那么你应该准备很多关于多线程的问题。在投资银行业务...

一只死笨死笨的猪
2014/09/30
335
0

没有更多内容

加载失败,请刷新页面

加载更多

3_数组

3_数组

行者终成事
今天
7
0
经典系统设计面试题解析:如何设计TinyURL(二)

原文链接:https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR 编者注:本文以一道经典的系统设计面试题:《如何设计TinyURL》的参考答案和解析为例,帮助...

APEMESH
今天
7
0
使用logstash同步MySQL数据到ES

概述   在生成业务常有将MySQL数据同步到ES的需求,如果需要很高的定制化,往往需要开发同步程序用于处理数据。但没有特殊业务需求,官方提供的logstash就很有优势了。   在使用logstas...

zxiaofan666
今天
10
0
X-MSG-IM-分布式信令跟踪能力

经过一周多的鏖战, X-MSG-IM的分布式信令跟踪能力已基本具备, 特点是: 实时. 只有要RX/TX就会实时产生信令跟踪事件, 先入kafka, 再入influxdb待查. 同时提供实时sub/pub接口. 完备. 可以完整...

dev5
今天
7
0
OpenJDK之CyclicBarrier

OpenJDK8,本人看的是openJDK。以前就看过,只是经常忘记,所以记录下 图1 CyclicBarrier是Doug Lea在JDK1.5中引入的,作用就不详细描述了,主要有如下俩个方法使用: await()方法,如果当前线...

克虏伯
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部