A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© ln0491 中级黑马   /  2015-9-16 09:22  /  1346 人查看  /  23 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

昨天看了视频,自己写了下,就不是出来

23 个回复

倒序浏览
这时我学习总结的,写出了一个例子

死锁出现的情况:同步嵌套同步

死锁例子:

public class DeadLock implements Runnable {
    private int flag;        //标识线程交替
    DeadLock(int flag){
            this.flag = flag;
    }
    static Object o1 = new Object(),o2 = new Object();        //定义两把锁
    public void run(){
        System.out.println("flag=" + flag +"---"+ Thread.currentThread());        //打印当前线程信息
        // 当flag==1锁住o1
        if (flag == 1) {
                synchronized (o1) {
                            System.out.println("101");
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                // 只要锁住o2就完成
                synchronized (o2) {
                    System.out.println("1");
                }
            }        
        }
        // 如果flag==0锁住o2
        if (flag == 0) {
            synchronized (o2) {
                try {
                        System.out.println("202");
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                // 只要锁住o1就完成
                synchronized (o1) {
                    System.out.println("0");
                }
            }
        }
    }
        public static void main(String[] args) {
        // 实例2个线程类
        DeadLock td1 = new DeadLock(0);
        DeadLock td2 = new DeadLock(1);

        // 开启2个线程
        Thread t1 = new Thread(td1);
        Thread t2 = new Thread(td2);
        t1.start();
        t2.start();
    }
}

运行结果:

flag=0--->Thread[Thread-0,5,main]
flag=1--->Thread[Thread-1,5,main]
202
101



flag=1--->Thread[Thread-1,5,main]
flag=0--->Thread[Thread-0,5,main]
101
202

理解:两个线程执行时,当Thread-0线程持有o1锁,线程Thread-1线程持有o2锁,

      此时两个锁都没有释放,Thread-0线程嵌套的同步代码块要获取o2锁,Thread-1线程嵌套的同步代码块要获取o1锁,

      但两个锁已被占用,均无法获取,程序到这里停止不动,就造成了死锁的情况

避免死锁:网络解释

    让所有的线程按照同样的顺序获得一组锁。这种方法消除了 X 和 Y 的拥有者分别等待对方的资源的问题。

  将多个锁组成一组并放到同一个锁下。前面Java线程死锁的例子中,可以创建一个银器对象的锁。于是在获得刀或叉之前都必须获得这个银器的锁。

  将那些不会阻塞的可获得资源用变量标志出来。当某个线程获得银器对象的锁时,就可以通过检查变量来判断是否整个银器集合中的对象锁都可获得。如果是,它就可以获得相关的锁,否则,就要释放掉银器这个锁并稍后再尝试。

  最重要的是,在编写代码前认真仔细地设计整个系统。多线程是困难的,在开始编程之前详细设计系统能够帮助你避免难以发现Java线程死锁的问题。
回复 使用道具 举报
jiaweizhang 发表于 2015-9-16 10:51
这时我学习总结的,写出了一个例子

死锁出现的情况:同步嵌套同步

谢谢,再慢慢理解下
回复 使用道具 举报
电脑太好了也是一个错。首先你确定你是锁的嵌套吗。第二 你的锁对象是几个(你很有可能是把锁对象搞错了)。能不能把你写的代码弄出来看看。
回复 使用道具 举报
球球_ 来自手机 中级黑马 2015-9-16 12:08:40
报纸
马上我们也学习线程了,我也不明白
回复 使用道具 举报
我们也快要学线程了
回复 使用道具 举报
插兜 中级黑马 2015-9-16 13:01:35
7#
二楼很棒
回复 使用道具 举报
好高深,没看懂
回复 使用道具 举报
死锁好像挺绕的,要先认真预习下
回复 使用道具 举报
嗯,学习了
回复 使用道具 举报
据我的 认识 死锁是随机出现的吧。  有时候会出现和谐的情况 就没问题 不知道楼主是不是遇到这种情况,还是我的技术太差 有误导你的成分在??
回复 使用道具 举报
锁内容比较重要,挺简单的,好好学
回复 使用道具 举报
package com.itheima;

class MyLock
{
        //定义两个Lock对象,代表两把锁
        static MyLock  locka = new MyLock ();
        static MyLock  lockb = new MyLock ();
}
class DeadLock implements Runnable
{       
        //定义一个标识符
        boolean flag;
        DeadLock(boolean flag)
        {
                this.flag = flag;
        }
       
        @Override
        public void run()
        {
                if(flag)
                {
                        synchronized(MyLock.locka)
                        {
                                System.out.println("if locka");
                                //lockb被另一个线程持有
                                synchronized(MyLock.lockb)
                                {
                                        System.out.println("if lockb");
                                }
                        }
                }
                else
                {
                        synchronized(MyLock.lockb)
                        {
                                System.out.println("else lockb");
                                //locka被另一个线程持有
                                synchronized(MyLock.locka)
                                {
                                        System.out.println("else locka");
                                }
                        }
                }
        }
}
public class Test026
{

        /**
         * 死锁的出现时因为同步代码块中嵌套同步代码块
         * @param args
         */
        public static void main(String[] args)
        {
                DeadLock dl1 = new DeadLock(true);
                DeadLock dl2 = new DeadLock(false);       
               
                new Thread(dl1).start();
                new Thread(dl2).start();       
        }

}
回复 使用道具 举报
jiaweizhang 发表于 2015-9-16 10:51
这时我学习总结的,写出了一个例子

死锁出现的情况:同步嵌套同步

两个锁为什么要静态的,普通的为什么不行
回复 使用道具 举报
两个锁为什么要静态的,普通的为什么不行
回复 使用道具 举报
史世锋 发表于 2015-9-16 22:21
package com.itheima;

class MyLock

两个锁为什么要静态的,普通的为什么不行
回复 使用道具 举报
ln0491 发表于 2015-9-17 11:44
两个锁为什么要静态的,普通的为什么不行

静态: 随着类的加载而加载---会随着类的消失而消失,生命周期最长
如果不是静态,你在代码中加入锁对象.toString(); 打印结果会是4个不同的地址
也就说相当于4把锁,当然锁不住,所有静态是保证锁对象只有两个
java.lang.Object@41bbee70
java.lang.Object@5b87a0b5
java.lang.Object@4f7c1837
java.lang.Object@554055b5

评分

参与人数 1黑马币 +10 收起 理由
ln0491 + 10 很给力!

查看全部评分

回复 使用道具 举报
jiaweizhang 发表于 2015-9-17 12:10
静态: 随着类的加载而加载---会随着类的消失而消失,生命周期最长
如果不是静态,你在代码中加入锁对象. ...

明白了,谢谢
回复 使用道具 举报

我也是看了很久才明白的{:2_32:}
回复 使用道具 举报
线程、、、、、、、、重点!学习二楼,谢谢
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马