`

锁的讲解

阅读更多

看代码:

public class TestDeadLock implements Runnable{

     int flag = 1;
     static Object o1 = new Object();  //资源1,也称为锁
    static Object o2 = new Object();  //资源2,也称为锁

 public static void main(String[] args) {
      TestDeadLock td1 = new TestDeadLock();
      TestDeadLock td2 = new TestDeadLock();
      td1.flag = 1;
      td2.flag = 0;
      Thread t1 = new Thread(td1);
      Thread t2 = new Thread(td2);
      t1.start();
      t2.start();
 }

 //锁,是个对象,给谁上锁,是给synchronized语句中的代码上锁,
 public void run() {
      if(flag == 1){
           synchronized(o1)
           {
                try {
                      Thread.sleep(1000);
                } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                }

                synchronized(o2){
                    System.out.println("t1 succeed");
                }
           }
      }

     if(flag == 0){
           synchronized(o2){
                try {
                     Thread.sleep(1000);
                } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                }

                synchronized(o1){
                      System.out.println("t2 succeed");
                }
           }
      }
 }

}

 (1)线程t1(td1)就相当于一个人。

 (2)对象o1就相当于一把锁。锁也可称为独占资源。

 (3)synchronized(o1)就相当于屋里的财富。

当线程t1运行到synchronized(o1)中,就相当于这个人走进了屋里,同时把屋的门给锁定(即o1锁定),当线程t1走出synchronized(o1)的代码段后,就相当于这个人走出了屋,同时把锁释放掉,别人(如t2)就可以拥有锁,可以进屋。

 

        我们来看上端代码,t1和t2两个线程,假设首先t1进入run()方法,然后判断flag是否为1,为1则利用对象o1将下面那段代码锁住,与此同时t2进入run()方法,判断flag,为0,则利用o2将下面那段代码锁住,再回过头来,此时t1继续向下执行,执行到synchronized(o2)这,此时o2对象已经被t2锁住,所以o1开始等待o2对象释放锁标记,同理,t2继续往下执行,执行到synchronized(o1)这,也就开始等待o1对象释放锁标记.这样互相等待,就产生死锁.
        注意:如果我把static Object o1 = new Object();前面的static去掉的话,那么就不会发生死锁了,这是因为,这两个线程都有自己的o1,即锁不再是公用的了,所以不会发生死锁了.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics