java的concurrent包中的鎖lock;工具類:CyclicBarrier、semaphore、CountDownLatch;集合:blockingquue、concurrentMap;原子量:aotmic。先從下面的圖開始,介紹下concurrent包的用法。
java
總結幾點如今知道的synchronized的異同,基本也就是個認知階段,並不能說明真實的原理信息。之後有時間在詳細的查閱官方資料:jvm
synchronized:
ide
一、JVM實現工具
二、能夠經過工具監控
性能
三、自動釋放
優化
四、在等待的的時候什麼都不能幹,只有等待喚醒(jvm喚醒、打斷)
ui
lock:
this
一、代碼實現、沒法監控。釋放在finally裏面
spa
二、獲取:能夠明確知道結果。固然,也就能夠作等待、或者直接作其餘操做
線程
三、釋放:以任何順序獲取和釋放多個鎖、釋放方式和偏向鎖相似
三、讀寫分離鎖分離
lock的實現和偏向鎖很相似,一個特色靈活,很是靈活。固然操做起來也更加困難,不過相信隨着Oracle持續的釋放黑科技優化jvm,synchronized性能愈來愈高。
lock的使用:
public interface Lock { //獲取鎖。若是鎖不可用,出於線程調度目的,將禁用當前線程,而且在得到鎖以前,該線程將一直處於休眠狀態。 void lock(); //若是當前線程未被中斷,則獲取鎖 void lockInterruptibly() throws InterruptedException; //僅在調用時鎖爲空閒狀態才獲取該鎖。若是鎖可用,則獲取鎖,並當即返回值 true。若是鎖不可用,則此方法將當即返回值 false。 boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void unlock(); Condition newCondition(); }
其中lock的標準用法:若是拿不到鎖就在隊列中等待
Lock l = ...; l.lock(); try { // access the resource protected by this lock } finally { l.unlock(); }
tryLock的用法:若是沒有獲取鎖,能夠直接作其餘的用處
Lock lock = ...; if (lock.tryLock()) { try { // manipulate protected state } finally { lock.unlock(); } } else { // perform alternative actions }
lockInterruptibly:獲取一個帶有中斷處理的鎖。例如:線程A獲取了鎖,則不能中斷。線程B會一直循環,而後自旋不端獲取鎖,或者查詢是否有中斷指令。在AbstractQueuedSynchronizer源碼中,doAcquireInterruptibly(int arg)方法能夠看出,是經過拋出異常來終端獲取鎖,在使用的時候須要用try。
public void testInterrupted() throws InterruptedException { lock.lockInterruptibly(); try{ //TODO: }finally{ lock.unlock(); } }
例子:lock
public class lockTest implements Runnable { private Lock lock; public lockTest(Lock lock) { this.lock = lock; } @Override public void run() { System.out.println("Thread Name: " + Thread.currentThread().getName() + " is begin"); lock.lock(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { System.out.println("Thread Name: " + Thread.currentThread().getName() + " is over"); lock.unlock(); } } public static void main(String[] args) { Lock lock = new ReentrantLock(); // ExecutorService es = Executors.newCachedThreadPool(); for (int i = 0; i < 100; i++) { new Thread(new lockTest(lock)).start(); ; } // es.shutdown(); } }
tryLock例子
public class TryLock implements Runnable { private Lock lock; public TryLock(Lock lock) { this.lock = lock; } @Override public void run() { if (lock.tryLock()) { System.out.println("Thread Name: " + Thread.currentThread().getName() + " is begin"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println("Thread Name: " + Thread.currentThread().getName() + " is over"); lock.unlock(); } } else { System.out.println("Thread Name: " + Thread.currentThread().getName() + " is not acquire"); } } public static void main(String[] args) { Lock lock = new ReentrantLock(); TryLock trylock = new TryLock(lock); new Thread(trylock).start(); new Thread(trylock).start(); } }
lockInterrupte:若是當前線程未被中斷,則獲取鎖。
public class LockInterrupt implements Runnable { private Lock lock; public LockInterrupt(Lock lock) { this.lock = lock; } private void testInterrupt() { try { lock.lockInterruptibly(); System.out.println("Thread Name: " + Thread.currentThread().getName() + " is begin"); // Thread.sleep(5000);// 睡眠阻塞、會被打斷 // for (;;) { } } catch (InterruptedException e1) { e1.printStackTrace(); } finally { System.out.println("Thread Name: " + Thread.currentThread().getName() + " is over"); lock.unlock(); System.out.println("Thread Name: " + Thread.currentThread().getName() + " is release"); } } @Override public void run() { this.testInterrupt(); } public static void main(String[] args) { try { Lock lock = new ReentrantLock(); LockInterrupt li = new LockInterrupt(lock); Thread t1 = new Thread(li, "t1"); Thread t2 = new Thread(li, "t2"); t1.start(); t2.start(); Thread.sleep(500); t1.interrupt(); // t2.interrupt();// 會將t1的sleep直接打斷、而後t2 } catch (InterruptedException e) { e.printStackTrace(); } } }
讀寫鎖ReentrantReadWriteLock:讀鎖能夠多個線程一塊兒使用。寫鎖只能線程獨享,這時候還會阻塞其它讀鎖、寫鎖
public class WritReadTest { private ReentrantReadWriteLock rrwl; public WritReadTest(ReentrantReadWriteLock lock) { this.rrwl = lock; } public void read() { try { rrwl.readLock().lock(); System.out.println("Thread Name: " + Thread.currentThread().getName() + " readlock is begin"); Thread.sleep(5000);// 睡眠阻塞、會被打斷 } catch (InterruptedException e1) { e1.printStackTrace(); } finally { System.out.println("Thread Name: " + Thread.currentThread().getName() + " readlock is over"); rrwl.readLock().unlock(); System.out.println("Thread Name: " + Thread.currentThread().getName() + " readlock is release"); } } public void write() { try { rrwl.writeLock().lock(); System.out.println("Thread Name: " + Thread.currentThread().getName() + " write is begin"); Thread.sleep(5000);// 睡眠阻塞、會被打斷 } catch (InterruptedException e1) { e1.printStackTrace(); } finally { System.out.println("Thread Name: " + Thread.currentThread().getName() + " write is over"); rrwl.writeLock().unlock(); System.out.println("Thread Name: " + Thread.currentThread().getName() + " write is release"); } } public static void main(String[] args) { ReentrantReadWriteLock rrwl = new ReentrantReadWriteLock(); WritReadTest wrt = new WritReadTest(rrwl); new Thread(new ReadTest(wrt)).start(); new Thread(new WriteTest(wrt)).start(); } } class ReadTest implements Runnable { public WritReadTest wrt; public ReadTest(WritReadTest wrt) { this.wrt = wrt; } @Override public void run() { // wrt.read(); wrt.write(); } } class WriteTest implements Runnable { private WritReadTest wrt; public WriteTest(WritReadTest wrt) { this.wrt = wrt; } @Override public void run() { wrt.write(); // wrt.read(); } }
condition:條件。代替Object的監視方法(wait、notify、notifyAll)。直接經過代碼將線程放入一個等待隊列,而後等待其它線程喚醒。
class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }