Java多线程(五):死锁

摘要:
死锁主要是由于设计问题。请参见示例ThreadDomain29类。在模拟图片中,线程持有一个锁,其他线程持有的锁的应用程序publicclassThreadDomain29{privatefinancialObjectobj1=newObject();privatefinationalObjectobj2=newObject);publicvoid obj1obj2()threwsException{synchronized{Thread.sleep;synchronized{System.out.println输入JConsole并单击“死锁检测”检测到死锁。从JavaVisualVM命令行输入jvisualvm以查找我们的进程并自动检测死锁。建议使用此方法以避免死锁。1.尽量少使用嵌套锁。

死锁

概念

当线程Thread-0持有锁Lock1,Thread-1持有锁Lock2,此时Thread-0申请Lock2锁的使用权,Thread-1申请Lock1锁的使用权,Thread-0和Thread-1都在无限地等待锁的使用权。这样就造成了死锁。
Java多线程(五):死锁第1张
死锁是主要由于设计的问题。一旦出现死锁,死锁的线程就会永远不能使用,同步方法不会被执行,死锁线程不会被自动终止,无尽地消耗CPU资源。

例子

看一个例子
ThreadDomain29类,模拟图片中,线程持有一个锁,申请被其他线程持有的锁的情况

public class ThreadDomain29 {
    private final Object obj1 = new Object();
    private final Object obj2 = new Object();

    public void obj1obj2() throws Exception
    {
        synchronized (obj1)
        {
            Thread.sleep(2000);
            synchronized (obj2)
            {
                System.out.println("obj1obj2 end!");
            }
        }
    }

    public void obj2obj1() throws Exception
    {
        synchronized (obj2)
        {
            Thread.sleep(2000);
            synchronized (obj1)
            {
                System.out.println("obj2obj1 end!");
            }
        }
    }
}

MyThread29_0类

public class MyThread29_0 extends Thread{
    private ThreadDomain29 dl;

    public MyThread29_0(ThreadDomain29 dl)
    {
        this.dl = dl;
    }

    public void run()
    {
        try
        {
            dl.obj1obj2();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

MyThread29_1类

public class MyThread29_1 extends Thread{
    private ThreadDomain29 dl;

    public MyThread29_1(ThreadDomain29 dl)
    {
        this.dl = dl;
    }

    public void run()
    {
        try
        {
            dl.obj2obj1();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

main方法

public class MyThread29_main {
    public static void main(String[] args)
    {
        ThreadDomain29 dl = new ThreadDomain29();
        MyThread29_0 t0 = new MyThread29_0(dl);
        MyThread29_1 t1 = new MyThread29_1(dl);
        t0.start();
        t1.start();

        while(true);
    }
}

因为发生了死锁,所以你不会看到任何结果。

死锁排查

jps+jstack

jps找到进程id
Java多线程(五):死锁第2张
jstack打印堆栈
输入jstack 10208
Java多线程(五):死锁第3张
可以看到,找到了两个死锁。

JConsole

命令行输入JConsole
Java多线程(五):死锁第4张
点击“检测死锁”
Java多线程(五):死锁第5张
已经检测到了死锁
Java多线程(五):死锁第6张

Java Visual VM

命令行输入jvisualvm
找到我们的进程
Java多线程(五):死锁第7张
自动检测到死锁,推荐使用这种方式

死锁避免

1.尽量少用嵌套的锁。
2.如果一定要用嵌套锁,那么请规定好获取锁的顺序。例子如下:

//伪代码
//condition1可以是属性值大小,hash值大小的比较等等
if(condition1){
            synchronized (obj2)
            {
                Thread.sleep(2000);
                synchronized (obj1)
                {
                    System.out.println("obj2obj1 end!");
                }
            }
        }else{
            synchronized (obj1)
            {
                Thread.sleep(2000);
                synchronized (obj2)
                {
                    System.out.println("obj1obj2 end!");
                }
            }
        }

3.使用Lock的tryLock方法,它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false,这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待。
后面讲到ReentrantLock会详细分析。

免责声明:文章转载自《Java多线程(五):死锁》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇WPF RadioButton 绑定枚举Android Studio 40个快捷键下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

java线程占多大的内存,占哪里的内存?

说到线程,我们往往想到的是线程安全、线程池,很少会去考虑线程的内存。 那么一个线程占用多大的内存?占用哪里的内存呢? 占多大的内存? jdk1.4默认的单个线程是占用256k的内存 jdk1.5+默认的单个线程是占用1M的内存 可以通过-Xss参数设定,一般默认就好 占哪里的内存? 这TM还用问?java线程当然是占用jvm的内存啊!(╯‵□′)╯︵┻━┻...

Java多线程-Object.wait()

  sleep()和yield()方法,不会释放锁,而wait()方法会释放当前线程的锁,所以,wait()方法必须是在同步代码块中调用。 应用场景   多个线程合作执行某项任务的时候,有线程A和线程B,它们使用同一对象锁,同一时间它们只有其中之一可以运行,另外一个线程处于等待状态。如下事件图表所示   线程A和线程B使用同一个把锁   线程A工作时,...

asp.net多线程(收藏)

1.ASP.NET多线程技术解析 http://developer.51cto.com/art/200907/138426.htm 2.(原创)asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例(二) 3.多线程范例 http://blog.csdn.net/gloomyboyo/archive/2006/08/09/104218...

C#多线程学习笔记之(abort与join配合使用)(转)

今天刚开始学多线程,尽管以前用过一点点,但是只是照着网上代码抄,没有真正理解,现在回过头来想研究研究,慢慢弄懂,下面就是我在网上所找资料的例子,相信大家都看过,做了小点改动 View Code 1 namespace 多线程 2 { 3 public class Simple 4 { 5 6 publ...

【Python之路】特别篇--多线程与多进程

并发 与 并行 的区别: 解释一:并发是在同一实体上的多个事件,并行是在不同实体上的多个事件; 解释二:并发是指两个或多个事件在同一时间间隔发生,而并行是指两个或者多个事件在同一时刻发生。 并发:就是同时做多件事情。 例如:终端用户程序利用并发功能,在输入数据的同时响应用户输入。服务器利用并发,在处理第一个请求的同时响应第二个请求。只要你希望程序同时做多件...

iOS之多线程浅谈

1)并发和并行的区别 在软件开发中不可避免的会遇到多线程的问题,在iOS客户端开发(或者.NET的winform或者wpf这样的cs程序)中就更不可避免的会用到多线程,在bs类型的web项目中要考虑一个并发问题,而在这里我们来说一下多线程的并行问题。 首先了解并发和并行的区别: 并发的实质是一个物理CPU(也可以多个物理CPU) 在若干道程序之间多路复用,...