Java多線程學習(九)

在JDK1.5中新增長了ReentrantLock類頁可以實現同步的效果,並且在擴張功能上也更增強大,使用上也更加方便。java

  1. ReentrantLock線程

    首先先看一下ReentrantLock的方法:code

    而後來看一個ReentrantLock的使用實例。對象

    public class Service extends Thread {
        private Lock lock = new ReentrantLock();
       public void run(){
           lock.lock();
           for(int i = 0; i < 5; i++){
               System.out.println(Thread,currentThread().getName());
           }
           lock.unLock();
       }
       
       public static void main(String [] args){
           Service s1 = new Service();
          Service s2 = new Service();
            Service s3 = new Service();
            s1.start();
            s2.start();
            s3.start();
    }
     
    運行結果:每一個線程是同步的,但哪一個線程先執行是不必定的。

    調用ReentrantLock對象的lock()方法獲取鎖,調用unlock()方法釋放鎖。unLock()方法也可放到finally代碼塊中。get

  2. Condition同步

    首先先看一下Condition類的方法:it

    Condition對象至關於「對象監視器」實例,線程對象能夠註冊在指定的Condition中,從而能夠有選擇性的進行線程通知,在調度線程上更加靈活。而synchronized就至關於整個Lock對象中就只有一個單一的Condition,全部線程都註冊到一個Condition中,線程開始notifyAll時,須要通知全部的WAITING線程。io

    public class MyThread extends Thread {
        private Lock lock = new ReentrantLock();
       private Condition condition = lock.newCondition();
       public void run(){
            lock.lock();
           condition.await();
           lock.unLock();
        }
        public static void main(String [] args){
             MyThread t = new MyThread();
             t.start();
        }      
    }

    在調用Condition的await方法以前,必需要先得到鎖,即必須先調用Lock的lock方法,不然會拋出異常。class

  3. 用Condition實現等待/通知模式效率

    Condition中的await()方法至關於wait()方法,signal()/signalAll()方法至關於notify()/notifyAll()方法。

    使用多個Condition實現通知部分線程

    既要先對線程組進行分類,而後在喚醒指定組中的線程

    public class MyService {
         private Lock lock = new ReentrantLock();
        private Condition conditionA = lock.newCondition();
        private Condition conditionB = lock.newCondition();
        public void awaitA(){
            lock.lock();
            conditionA.await();
            lock.unLock();
         }
         public void awaitB(){
            lock.lock();
            conditionB.await();
            lock.unLock();
         }
         public void signalA(){
            lock.lock();
           conditionA.signalAll();
           lock.unLock();
         }
         public void signalB(){
            lock.lock();
            conditionB.signalAll();
            lock.unLock();
         }    
     }

    調用conditionB的signalAll方法只有ConditionB的waiting線程被喚醒,而不會喚醒conditionAl的waiting線程。

  4. 公平鎖與非公平鎖

    公平鎖表示線程獲取鎖的順序是按照線程加鎖的順序來分配的,即按照先進先出的順序。打印結果基本有序。

    非公平鎖就是一種獲取鎖的搶佔機制,是隨機得到鎖的,某些線程可能一直都拿不到鎖。打印結果基本亂序。默認的

    Lock lock = new ReentrantLock(true);  //公平鎖

    Lock lock = new ReentrantLock(false);  //非公平鎖

  5. 使用ReentrantReadWriteLock類

    ReentrantLock類具備徹底互斥排他的效果,即同一個時間內只有一個線程在執行lock方法後面的任務。這樣的效率極低。因此JDK中提供了一種ReentrantReadWriteLock類,在某些不須要操做實例變量的方法中,能夠提升代碼執行速度。

    讀寫鎖有兩個鎖,一個是讀操做相關的鎖,稱爲共享鎖;另外一個是寫操做相關的鎖,稱爲排它鎖。多個讀鎖之間不互斥,讀鎖和寫鎖互斥,寫鎖和寫鎖互斥。在沒有線程進行寫入操做時,進行讀操做的多個線程均可以獲取鎖,而進行寫操做的線程只有在獲取寫鎖以後才能進行寫入操做。即多個線程能夠同時進行讀取操做,可是同一個時刻只容許一個線程進行寫操做。

    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    lock.readLock().lock();

    lock.writeLock().lock();

相關文章
相關標籤/搜索