WEB开发网
开发学院软件开发Java 多线程基础总结一--synchronized 阅读

多线程基础总结一--synchronized

 2010-01-22 00:00:00 来源:WEB开发网   
核心提示: 假设场景:线程A调用methodOne(),获得lock1的隐式锁后,多线程基础总结一--synchronized(3),在获得lock2的隐式锁之前线程B进入运行,调用 methodTwo(),下面简单的讲讲 java.lang.Thread的特色小故事,(待续...) PS:"多线

假设场景:线程A调用methodOne(),获得lock1的隐式锁后,在获得lock2的隐式锁之前线程B进入运行,调用 methodTwo(),抢先获得了lock2的隐式锁,此时线程A等着线程B交出lock2,线程B等着lock1进入方法块,死锁就这样被创造出来了。

以上的例子不直观的话,再看一个实例顺便看看wait()的缺陷:

Java代码  

import java.util.LinkedList; 
import java.util.List; 
 
/** 
 * User: yanxuxin 
 * Date: Dec 9, 2009 
 * Time: 5:58:39 PM 
 */ 
public class DeadLockSample { 
  public static void main(String[] args) { 
    final WaitAndNotify wan = new WaitAndNotify(); 
 
    Thread t1 = new Thread(new Runnable(){ 
      public void run() { 
       wan.pop(); 
      } 
    }); 
 
    Thread t2 = new Thread(new Runnable(){ 
      public void run() { 
       wan.push("a"); 
      } 
    }); 
 
    t1.start(); 
    t2.start(); 
  } 
} 
 
class WaitAndNotify { 
 
  final List<String> list = new LinkedList<String>(); 
 
  public synchronized void push(String x) { 
    synchronized(list) { 
      list.add(x); 
      notify(); 
    } 
  } 
 
  public synchronized Object pop() { 
    synchronized(list) { 
      if(list.size() <= 0) { 
        try { 
          wait(); 
        } catch (InterruptedException e) { 
          e.printStackTrace(); 
        } 
      } 
      return list.size(); 
    } 
  } 
 
}

上面的这个例子也会出现死锁,为什么呢?首先看WaitAndNotify这个类,在push和pop方法上有synchronized关键字,方法内部也有synchronized,那么当WaitAndNotify实例化时会有两个对象的隐式锁,一个是WaitAndNotify对象自身的,作用在方法上;另一个就是方法内部同步用到的list的。主线程开启两个线程t1和t2,t1进入pop方法此时list为空,它先后获得了wan和 list的隐式锁,接着就被wait扔进wait set等待去了。注意这个wait()方法是谁的?答案是wan的,所以它释放了wan的隐式锁,但是把list的死死的抓着不放。此时t2终于得到了 wan的隐式锁进入push方法,但是不幸的是list的隐式锁它这辈子也得不到了。。。

就是由于wait的设计是针对对象管理线程的,而又没有其他的可以类似栈的方式层层释放锁,导致死锁的杯具了。关于synchronized和 wait(),notify(),notifyAll()的故事,我想我能瞎编的暂时这么多了,不然滔滔江水就又杯具了,哈哈。下面简单的讲讲 java.lang.Thread的特色小故事。(待续...)

PS:"多线程基础总结六"算是本文的补遗了,呵呵。

上一页  1 2 3 

Tags:线程 基础 总结

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接