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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© b_boywindy 中级黑马   /  2012-2-20 09:29  /  2810 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

看了一写资料 但是还是不太明白死锁的概念,求帮忙?

该贴已经同步到 b_boywindy的微博

4 个回复

倒序浏览
一个最简单的例子就是有资源A和资源B,都是不可剥夺资源,现在进程C已经申请了资源A,进程D也申请了资源B,进程C接下来的操作需要用到资源B,而进程D恰好也在申请资源A,那么就引发了死锁。这个肯定每个人都看过了。然后套用回去定义:如果一个进程集合里面(进程C和进程D)的每个进程(进程C和进程D)都在等待只能由这个集合中的其他一个进程(对于进程C,他在等进程D;对于进程D,他在等进程C)才能引发的事件(释放相应资源)。

这里的资源包括了软的资源(代码块)和硬的资源(例如扫描仪)。资源一般可以分两种:可剥夺资源(Preemptable)和不可剥夺资源(Nonpreemptable)。一般来说对于由可剥夺资源引起的死锁可以由系统的重新分配资源来解决,所以一般来说大家说的死锁都是由于不可剥夺资源所引起的。

死锁的四个必要条件

互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。
请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源。
非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
循环等待条件(Circular wait):系统中若干进程组成环路,改环路中每个进程都在等待相邻进程正占用的资源。
回复 使用道具 举报
给一段代码线程死锁的代码你看一下:

class Test implements Runnable{

        private static final String KEY1="KEY1";
        private static final String KEY2="KEY2";
        private boolean lock;
        public Test(boolean lock){
                this.lock = lock;

        }
        public void run(){
                if(lock){
                        synchronized(KEY1){//第一次锁KEY1
                                try{
                                        Thread.sleep(3000);
                                }catch(Exception e){                                       
                                }
                                System.out.println("给我KEY2我要使用!");
                                synchronized(KEY2){//第二次锁KEY2
                                        System.out.println("我拿到KEY2运行结束!");
                                }
                        }
                }else{
                        synchronized(KEY2){//第一次锁KEY2
                                try{
                                        Thread.sleep(3000);
                                }catch(Exception e){                                       
                                }
                                System.out.println("Give me KEY1,I will use!");
                                synchronized(KEY1){//第二次锁KEY1
                                        System.out.println("我拿到KEY1运行结束!");
                                }
                        }
                }
        }

        public static void main(String args[]){
                new Thread(new Test(true)).start();
                new Thread(new Test(false)).start();
        }
}

其实线程死锁很简单:由于线程能被阻塞,更由于synchronized方法能阻止其他线程访问本对象,因此可能会造成线程一等待线程二释放某个对象。线程二又等待线程一释放对象。这样就形成了一个环。每个线程都在等待对方释放资源。而它们谁都不能运行,这就造成了死锁了。
回复 使用道具 举报
简单的说吧
一个方法:
synchronized(A.obj)
{
   synchronized(B.obj)
}

synchronized(B.obj)
{
   synchronized(A.obj)
}


回复 使用道具 举报
当一个线程等待由另一个线程持有的锁,而后者正在等待已被第一个线程持有的锁时,就会发生死锁。

就是彼此需要对方占用的资源,而彼此又不肯释放自己占有的资源,等待对方释放资源。

发生死锁必须同时满足的四个条件:

1)互斥条件。线程中使用的资源中至少要有一个是不能共享的。
2)至少有一个线程它必须持有一个资源且正在等待获取一个当前被别的线程持有的资源。
3)资源不能被线程抢占。
4)必须有循环等待,这时,一个线程等待其他线程所持有的资源,后者又在等待另一个线程所持有的资源。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马