簡述synchronized和java.util.concurrent.locks.Lock的異同

簡述synchronized和java.util.concurrent.locks.Lock的異同 
源碼來自一篇Java基礎題 

主要相同點:Lock能完成synchronized所實現的全部功能 
主要不一樣點:Lock有比synchronized更精確的線程語義和更好的性能。synchronized會自動釋放鎖,而Lock必定要求程序員手工釋放,而且必須在finally從句中釋放(由於若是不在finally中釋放的狀況,當拋出異常時,線程直接死掉,可是沒有釋放鎖,使得其餘相關線程沒法執行。讀者能夠試試在定義一個數組,並訪問越界區,使得程序拋出異常,可是釋放鎖並未在finally中)。java

 

源碼例子: 程序員

Java代碼 數組

  1. package test.thread;  
  2. import java.util.concurrent.locks.Lock;  
  3. import java.util.concurrent.locks.ReentrantLock;  
  4. public class TestLock {  
  5.     private int j;  
  6.     private Lock lock = new ReentrantLock();  
  7.     public static void main(String[] args) {  
  8.         TestLock tt = new TestLock();  
  9.         for (int i = 0; i < 2; i++) {  
  10.             new Thread(tt.new Adder()).start();  
  11.             new Thread(tt.new Subtractor()).start();  
  12.         }  
  13.     }  
  14.     private class Subtractor implements Runnable {  
  15.         @Override  
  16.         public void run() {  
  17.             for (int i = 0; i < 15; i++) {  
  18.                 // 這裏拋異常了,鎖能釋放嗎?會釋放,可是lock就不會釋放,因此須要加上try..catch  
  19.                 /*synchronized (TestLock.this) {  
  20.                     System.out.println("j--=" +j--); 
  21.                 }*/  
  22.                 lock.lock();  
  23.                 try {  
  24.                     System.out.println("j--=" + j--);  
  25.                 } finally {  
  26.                     lock.unlock();  
  27.                 }  
  28.             }  
  29.         }  
  30.     }  
  31.     private class Adder implements Runnable {  
  32.         @Override  
  33.         public void run() {  
  34.             for (int i = 0; i < 15; i++) {  
  35.                  /*synchronized (TestLock.this) { 
  36.                      System.out.println("j++="+j++);  
  37.                  }*/  
  38.                 lock.lock();  
  39.                 try {  
  40.                     System.out.println("j++=" + j++);  
  41.                 } finally {  
  42.                     lock.unlock();  
  43.                 }  
  44.             }  
  45.         }  
  46.     }  
  47. }  



Lock還有更強大的功能,例如,它的tryLock方法能夠非阻塞方式去拿鎖。 
tryLock() 
tryLock(long timeout, TimeUnit timeUnit) 

trylock()方法:若是獲取了鎖當即返回true,若是別的線程正持有鎖,當即返回false; 

tryLock(long timeout, TimeUnit timeUnit)方法:若是獲取了鎖定當即返回true,若是別的線程正持有鎖,會等待參數給定的時間,在等待的過程當中,若是獲取了鎖定,就返回true,若是等待超時,返回false; 
是否是比synchronized靈活就體現出來了,好比:你如今正在忙於工做,忽然感受內急,因而你跑向洗手間,到門口發現一個「清潔中,暫停使用」的牌牌。沒辦法,工做又忙,因此你只好先放棄去洗手間回去忙工做,可能如此反覆,終於你發現能夠進了,因而...... 
若是用synchronized,當你發現洗手間沒法暫時沒法進入時,就只能乖乖在門口乾等了。 
而使用trylock()呢,首先你試着去洗手間,發現暫時沒法進入(trylock返回false),因而你繼續忙你的工做,如此反覆,直到能夠進入洗手間爲止(trylock返回true)。甚至,你很是急,你能夠嘗試性的在門口等20秒,不行再去忙工做(trylock(20, TimeUnit.SECONDS);)。 ide

相關文章
相關標籤/搜索