學習wait、notify和synchronized及Lock


 概  述


1. 多線程同步相關java封裝類:java.util.concurrent.locks. 包下;
    1)線程的生命周期:初始化、就緒、運行、阻塞、死亡
    2)Java中對線程定義的6種狀態:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED
    3)線程的狀態轉換過程
      從 NEW到 RUNNABLE狀態
      NEW狀態的線程,不會被操作系統調度,因此不會執行。Java線程要執行,就必須轉換到 RUNNABLE狀態。從NEW轉到RUNNABLE狀態,只要調用線程對象的start()方法就可以了。
      從 RUNNABLE 到 TERMINATED 狀態
      線程執行完run()方法后,會自動轉換到 TERMINATED 狀態;當然如果執行run()方法的時候異常拋出,也會導致線程終止;有時我們需要強制中斷run()方法的執行,例如run()方法訪問一個很慢的網絡,我們想終止怎么辦呢?Java的Thread類里面有個stop()方法,不過已經標記為 @Deprecated,所以不建議使用了。正確的姿勢其實是調用interrupt()方法。
      stop()方法會真的殺死線程,不給線程喘息的機會,如果線程持有 ReentrantLock 鎖,被 stop() 的線程並不會自動調用ReentrantLock的unlock()去釋放鎖,那其他線程就再也沒機會獲得 ReentrantLock 鎖,這實在是太危險了。所以該方法就不建議使用了,類似的方法還有 suspend() 和 resume() 方法,這兩個方法同樣也都不建議使用了,所以這里也就不多介紹了。
      而interrupt() 方法就溫柔多了,interrupt()方法僅僅是通知線程,線程有機會執行一些后續操作,同時也可以無視這個通知。被interrupt的線程,是怎么收到通知的呢?一種是異常,另一種是主動檢測。
2. 關於Lock接口
    1)獲取鎖
       lock()     無返回值
       tryLock()   有返回值
       tryLock(long time, TimeUnit unit)   在一定時間內獲取鎖
       lockInterruptibly()  未獲取到鎖,會響應中斷(拋出異常)
    2)釋放鎖
       unLock()
    3)實現類
       ReentrantLock: 可重入鎖 唯一實現Lock接口
3. 關於ReadWriteLock(讀寫鎖)接口
    如果有一個線程已經占用了讀鎖,則此時其他線程要申請讀鎖,也可以同時獲取到讀鎖。
    如果有一個線程已經占用了讀鎖,則此時其他線程如果要申請寫鎖,則申請寫鎖的線程會一直等待釋放讀鎖。
    如果有一個線程已經占用了寫鎖,則此時其他線程如果申請寫鎖或者讀鎖,則申請的線程會一直等待釋放寫鎖。    
    1)獲取鎖
        readLock()  獲取讀鎖
        writeLock()  獲取寫鎖
    2)釋放鎖
        readLock().unLock()  釋放讀鎖
        writeLock().unLock()  釋放寫鎖
    3)實現類
       ReentrantReadWriteLock: 可重入鎖 唯一實現Lock接口
4. 相關概念
    1). 可重入鎖
    如果鎖具備可重入性,則稱作為可重入鎖。像synchronized和ReentrantLock都是可重入鎖,
    可重入性實際上表明了鎖的分配機制:基於線程的分配,而不是基於方法調用的分配。
    舉個簡單的例子,當一個線程執行到某個synchronized方法時,比如說method1,而在method1中會調用另外一個synchronized方法method2,此時線程不必重新去申請鎖,而是可以直接執行方法method2。
    簡單的理解:線程已經具備鎖,不必再申請鎖,可一直執行完畢。
    2). 可中斷鎖
    在Java中,synchronized就不是可中斷鎖,而Lock是可中斷鎖。
    3). 公平鎖
    公平鎖即盡量以請求鎖的順序來獲取鎖。
    synchronized就是非公平鎖,它無法保證等待的線程獲取鎖的順序。
    而對於ReentrantLock和ReentrantReadWriteLock,它默認情況下是非公平鎖,但是可以設置為公平鎖。
    ReentrantLock中靜態內部類:1)NotFairSync實現非公平鎖;2)FairSync實現公平鎖
    ReentrantLock lock = new ReentrantLock(true); 參數為true表示為公平鎖,為fasle為非公平鎖
    4). 讀寫鎖
    正因為有了讀寫鎖,才使得多個線程之間的讀操作不會發生沖突。
     ReadWriteLock就是讀寫鎖,它是一個接口,ReentrantReadWriteLock實現了這個接口。
     可以通過readLock()獲取讀鎖,通過writeLock()獲取寫鎖。
5. Lock和synchronized的區別
    1)Lock是一個接口,而synchronized是Java中的關鍵字,synchronized是內置的語言實現;
    2)synchronized在發生異常時,會自動釋放線程占有的鎖,因此不會導致死鎖現象發生;
       而Lock在發生異常時,如果沒有主動通過unLock()去釋放鎖,則很可能造成死鎖現象,
       因此使用Lock時需要在finally塊中釋放鎖;
    3)Lock可以讓等待鎖的線程響應中斷,而synchronized卻不行,使用synchronized時,
       等待的線程會一直等待下去,不能夠響應中斷;
    4)通過Lock可以知道有沒有成功獲取鎖,而synchronized卻無法辦到。
    5)Lock可以提高多個線程進行讀操作的效率。
    在性能上來說,如果競爭資源不激烈,兩者的性能是差不多的,而當競爭資源非常激烈時(即有大量線程同時競爭),
    此時Lock的性能要遠遠優於synchronized。所以說,在具體使用時要根據適當情況選擇。
6. Object下的鎖:
    wait():釋放占有的對象鎖
    notify(): 該方法會喚醒因為調用對象的wait()而等待的線程
    notifyAll()則是喚醒所有等待的線程

 

  一、 java多線程同步:synchronized及wait()、notify()

 

 1 import java.util.Random;
 2 import java.util.concurrent.*;
 3 
 4 public class MyProductAndConsume {
 5 
 6     volatile static int NUM = 1;
 7 
 8     AtomicInteger atomicInteger = new AtomicInteger(0);
 9 
10     final Object productLock = Object.class;
11     final Object consumeLock = int[].class;
12     final ReentrantLock lock = new ReentrantLock();
13 
14     final class MyWorkProduct implements Callable {
15         public Object call() throws Exception{
16             while (true) {
17                 Thread.sleep(500);
18                 synchronized (atomicInteger) {
19                     while (atomicInteger.get() >= 1)  //已有生產的產品(while是為了同時只能一個生產者工作)
20                         atomicInteger.wait(); //阻塞當前線程
21                     System.out.println(Thread.currentThread().getName() + "-MyWorkProduct : " + ++NUM);
22                     atomicInteger.incrementAndGet();
23                     atomicInteger.notifyAll();
24                 }
25             }
26         }
27     }
28 
29     final class MyWorkConsume implements Callable {
30         public Object call() throws Exception{
31             while (true) {
32                 Thread.sleep(new Random().nextInt(8000) + 500);
33                 synchronized (atomicInteger) {
34                     while (atomicInteger.get() <= 0)  //無可消費產品(while是為了同時只能一個消費者消費)
35                         atomicInteger.wait();
36                     System.out.println(Thread.currentThread().getName() + "-MyWorkConsume : " + NUM);
37                     atomicInteger.getAndDecrement();
38                     atomicInteger.notifyAll();
39                 }
40             }
41         }
42     }
43 
44     public void execute() {
45         ExecutorService executorService = Executors.newFixedThreadPool(5);
46         executorService.submit(new MyWorkProduct());executorService.submit(new MyWorkProduct());
47         executorService.submit(new MyWorkConsume());executorService.submit(new MyWorkConsume());executorService.submit(new MyWorkConsume());
48     }
49 
50     public static void main(String[] args) {
51         new MyProductAndConsume().execute();
52     }
53 }

 

運行結果:

pool-1-thread-2-MyWorkProduct : 2
pool-1-thread-3-MyWorkConsume : 2
pool-1-thread-2-MyWorkProduct : 3
pool-1-thread-4-MyWorkConsume : 3
pool-1-thread-1-MyWorkProduct : 4
pool-1-thread-5-MyWorkConsume : 4
pool-1-thread-1-MyWorkProduct : 5
pool-1-thread-3-MyWorkConsume : 5
pool-1-thread-1-MyWorkProduct : 6
pool-1-thread-5-MyWorkConsume : 6
pool-1-thread-2-MyWorkProduct : 7
pool-1-thread-4-MyWorkConsume : 7
pool-1-thread-1-MyWorkProduct : 8
pool-1-thread-4-MyWorkConsume : 8
pool-1-thread-1-MyWorkProduct : 9
pool-1-thread-4-MyWorkConsume : 9
pool-1-thread-1-MyWorkProduct : 10
pool-1-thread-3-MyWorkConsume : 10 …………

 示例二:

  1 package com.cheng2839.test;
  2 
  3 import com.cheng2839.util.Logger;
  4 
  5 /**
  6  * java多線程同步
  7  * 1. synchronized修飾方法[參見syncFunOne]
  8  * 2. synchronized同步塊(普通類成員變量)[參見syncFunTwo]
  9  * 3. synchronized同步塊(static類成員變量)[參見syncFunThree]
 10  * 4. wait()及notify()的用法[參見syncFunFour1、syncFunFour2]
 11  *
 12  * @author cheng2839
 13  * @date 2018年11月16日
 14  */
 15 public class MyThreadTest001 {
 16 
 17     //此處定義一個靜態類成員變量,供所有線程共用[共用信號量]
 18     public static int NUM;
 19 
 20     //Object成員變量
 21     private Object lock = new Object();
 22 
 23     //Object靜態類成員變量
 24     private static final Object LOCK = new Object();
 25 
 26     //初始化信號量值
 27     public MyThreadTest001() {
 28         NUM = 1;
 29     }
 30 
 31     /**
 32      * synchronize修飾的方法,表示該方法是同步的
 33      */
 34     public synchronized void syncFunOne() {
 35         Logger.info(Thread.currentThread()+" - syncFunOne before : " + NUM);
 36         NUM++;
 37         Logger.info(Thread.currentThread()+" - syncFunOne after : " + NUM);
 38     }
 39 
 40     /**
 41      * synchronize修飾的代碼塊,表示該方法中被synchronized修飾的代碼塊是同步的
 42      */
 43     public void syncFunTwo() {
 44         synchronized(lock) {
 45             Logger.info(Thread.currentThread()+" - syncFunTwo before : " + NUM);
 46             NUM++;
 47             Logger.info(Thread.currentThread()+" - syncFunTwo after : " + NUM);
 48         }
 49     }
 50 
 51     /**
 52      * synchronize修飾的代碼塊,表示該方法中被synchronized修飾的代碼塊是同步的
 53      */
 54     public void syncFunThree() {
 55         synchronized(LOCK) {
 56             Logger.info(Thread.currentThread()+" - syncFunThree before : " + NUM);
 57             NUM++;
 58             Logger.info(Thread.currentThread()+" - syncFunThree after : " + NUM);
 59         }
 60     }
 61 
 62     /**
 63      * lock.wait()表示等待被lock對象實例的notify()喚醒,才可繼續執行
 64      * 注意:使用wait()必須被synchronized修飾
 65      *       wait()和notify()配對使用,表示在執行上有先后順序
 66      */
 67     public void syncFunFour1() {
 68         try {
 69             while (true) {
 70                 synchronized (lock) {
 71                     lock.wait(); //等待被喚醒
 72                     Logger.info(Thread.currentThread()+" - syncFunFour1 before : " + NUM);
 73                     NUM++;
 74                     Logger.info(Thread.currentThread()+" - syncFunFour1 after : " + NUM);
 75                 }
 76             }
 77         }catch (InterruptedException e){}
 78     }
 79 
 80     /**
 81      * lock.notify()表示實例喚醒一個被lock對象wait()的線程
 82      * 注意:使用notify()必須被synchronized修飾
 83      *       wait()和notify()配對使用,表示在執行上有先后順序
 84      */
 85     public void syncFunFour2() {
 86         try {
 87             while (true) {
 88                 synchronized (lock) {
 89                     Logger.info(Thread.currentThread()+" - syncFunFour2 before : " + NUM);
 90                     NUM--;
 91                     Logger.info(Thread.currentThread()+" - syncFunFour2 after : " + NUM);
 92                     lock.notify(); //喚醒一個wait的線程
 93                 }
 94                 Logger.info(Thread.currentThread()+" - sleep beginning.");
 95                 Thread.sleep(3000);
 96                 Logger.info(Thread.currentThread()+" - sleep finished.");
 97             }
 98         }catch (InterruptedException e){}
 99     }
100 
101     /**
102      * 測試wait()和notify()
103      * @param test001
104      */
105     public void testWait(MyThreadTest001 test001){
106         //執行順序是:對信號量先減1,再喚醒加1線程,每3秒循環執行一次
107         new Thread(() -> test001.syncFunFour1()).start(); //對信號量進行加1操作
108         new Thread(() -> test001.syncFunFour2()).start(); //對信號量進行減1操作
109     }
110 
111 
112     public static void main(String[] args) {
113         MyThreadTest001 test001 = new MyThreadTest001();
114 
115         //測試synchronized
116         //創建threadCount個線程,對同一信號量進行加1操作,保證信號量同時只被一個線程操作,保證了信號量的一致性
117         int threadCount = 5;
118         while (threadCount-->0) {
119             Thread thread = new Thread(new TestThread(test001));
120             thread.start();
121         }
122 
123         //測試wait()和notify()
124 //        test001.testWait(test001);
125 
126     }
127 }
128 
129 /**
130  * 創建一個線程
131  */
132 class TestThread implements Runnable{
133     private MyThreadTest001 test001;
134     public TestThread(MyThreadTest001 test001) {
135         this.test001 = test001;
136     }
137     public void run() {
138         try {
139             //每個線程每隔50毫秒並循環調用5次
140             for (int i=0;i<5;i++) {
141                 test001.syncFunOne(); //此處可以切換為syncFunTwo、syncFunThree進行測試
142 //                test001.syncFunTwo();
143 //                test001.syncFunThree();
144                 Thread.sleep(50);
145             }
146         }catch (InterruptedException e) {}
147     }
148 }

 

  測試打印結果:

  1 --------------------測試syncFunOne()的打印結果如下--------------------
  2 2018-11-16 23:08:56.047    [INFO]    Thread[Thread-0,5,main] - syncFunOne before : 1
  3 2018-11-16 23:08:56.048    [INFO]    Thread[Thread-0,5,main] - syncFunOne after : 2
  4 2018-11-16 23:08:56.049    [INFO]    Thread[Thread-4,5,main] - syncFunOne before : 2
  5 2018-11-16 23:08:56.049    [INFO]    Thread[Thread-4,5,main] - syncFunOne after : 3
  6 2018-11-16 23:08:56.049    [INFO]    Thread[Thread-3,5,main] - syncFunOne before : 3
  7 2018-11-16 23:08:56.049    [INFO]    Thread[Thread-3,5,main] - syncFunOne after : 4
  8 2018-11-16 23:08:56.049    [INFO]    Thread[Thread-2,5,main] - syncFunOne before : 4
  9 2018-11-16 23:08:56.049    [INFO]    Thread[Thread-2,5,main] - syncFunOne after : 5
 10 2018-11-16 23:08:56.049    [INFO]    Thread[Thread-1,5,main] - syncFunOne before : 5
 11 2018-11-16 23:08:56.049    [INFO]    Thread[Thread-1,5,main] - syncFunOne after : 6
 12 2018-11-16 23:08:56.100    [INFO]    Thread[Thread-2,5,main] - syncFunOne before : 6
 13 2018-11-16 23:08:56.100    [INFO]    Thread[Thread-2,5,main] - syncFunOne after : 7
 14 2018-11-16 23:08:56.100    [INFO]    Thread[Thread-0,5,main] - syncFunOne before : 7
 15 2018-11-16 23:08:56.100    [INFO]    Thread[Thread-0,5,main] - syncFunOne after : 8
 16 2018-11-16 23:08:56.100    [INFO]    Thread[Thread-3,5,main] - syncFunOne before : 8
 17 2018-11-16 23:08:56.100    [INFO]    Thread[Thread-3,5,main] - syncFunOne after : 9
 18 2018-11-16 23:08:56.100    [INFO]    Thread[Thread-4,5,main] - syncFunOne before : 9
 19 2018-11-16 23:08:56.100    [INFO]    Thread[Thread-4,5,main] - syncFunOne after : 10
 20 2018-11-16 23:08:56.101    [INFO]    Thread[Thread-1,5,main] - syncFunOne before : 10
 21 2018-11-16 23:08:56.101    [INFO]    Thread[Thread-1,5,main] - syncFunOne after : 11
 22 2018-11-16 23:08:56.151    [INFO]    Thread[Thread-3,5,main] - syncFunOne before : 11
 23 2018-11-16 23:08:56.151    [INFO]    Thread[Thread-3,5,main] - syncFunOne after : 12
 24 2018-11-16 23:08:56.151    [INFO]    Thread[Thread-2,5,main] - syncFunOne before : 12
 25 2018-11-16 23:08:56.151    [INFO]    Thread[Thread-2,5,main] - syncFunOne after : 13
 26 2018-11-16 23:08:56.151    [INFO]    Thread[Thread-0,5,main] - syncFunOne before : 13
 27 2018-11-16 23:08:56.151    [INFO]    Thread[Thread-0,5,main] - syncFunOne after : 14
 28 2018-11-16 23:08:56.152    [INFO]    Thread[Thread-4,5,main] - syncFunOne before : 14
 29 2018-11-16 23:08:56.152    [INFO]    Thread[Thread-4,5,main] - syncFunOne after : 15
 30 2018-11-16 23:08:56.152    [INFO]    Thread[Thread-1,5,main] - syncFunOne before : 15
 31 2018-11-16 23:08:56.152    [INFO]    Thread[Thread-1,5,main] - syncFunOne after : 16
 32 2018-11-16 23:08:56.202    [INFO]    Thread[Thread-0,5,main] - syncFunOne before : 16
 33 2018-11-16 23:08:56.202    [INFO]    Thread[Thread-0,5,main] - syncFunOne after : 17
 34 2018-11-16 23:08:56.202    [INFO]    Thread[Thread-2,5,main] - syncFunOne before : 17
 35 2018-11-16 23:08:56.202    [INFO]    Thread[Thread-2,5,main] - syncFunOne after : 18
 36 2018-11-16 23:08:56.202    [INFO]    Thread[Thread-3,5,main] - syncFunOne before : 18
 37 2018-11-16 23:08:56.202    [INFO]    Thread[Thread-3,5,main] - syncFunOne after : 19
 38 2018-11-16 23:08:56.203    [INFO]    Thread[Thread-4,5,main] - syncFunOne before : 19
 39 2018-11-16 23:08:56.203    [INFO]    Thread[Thread-4,5,main] - syncFunOne after : 20
 40 2018-11-16 23:08:56.203    [INFO]    Thread[Thread-1,5,main] - syncFunOne before : 20
 41 2018-11-16 23:08:56.203    [INFO]    Thread[Thread-1,5,main] - syncFunOne after : 21
 42 2018-11-16 23:08:56.253    [INFO]    Thread[Thread-0,5,main] - syncFunOne before : 21
 43 2018-11-16 23:08:56.253    [INFO]    Thread[Thread-0,5,main] - syncFunOne after : 22
 44 2018-11-16 23:08:56.253    [INFO]    Thread[Thread-2,5,main] - syncFunOne before : 22
 45 2018-11-16 23:08:56.253    [INFO]    Thread[Thread-2,5,main] - syncFunOne after : 23
 46 2018-11-16 23:08:56.253    [INFO]    Thread[Thread-3,5,main] - syncFunOne before : 23
 47 2018-11-16 23:08:56.253    [INFO]    Thread[Thread-3,5,main] - syncFunOne after : 24
 48 2018-11-16 23:08:56.254    [INFO]    Thread[Thread-4,5,main] - syncFunOne before : 24
 49 2018-11-16 23:08:56.254    [INFO]    Thread[Thread-4,5,main] - syncFunOne after : 25
 50 2018-11-16 23:08:56.254    [INFO]    Thread[Thread-1,5,main] - syncFunOne before : 25
 51 2018-11-16 23:08:56.254    [INFO]    Thread[Thread-1,5,main] - syncFunOne after : 26
 52 
 53 
 54 --------------------測試syncFunTwo()的打印結果如下--------------------
 55 2018-11-16 23:09:24.966    [INFO]    Thread[Thread-0,5,main] - syncFunTwo before : 1
 56 2018-11-16 23:09:24.966    [INFO]    Thread[Thread-0,5,main] - syncFunTwo after : 2
 57 2018-11-16 23:09:24.967    [INFO]    Thread[Thread-4,5,main] - syncFunTwo before : 2
 58 2018-11-16 23:09:24.967    [INFO]    Thread[Thread-4,5,main] - syncFunTwo after : 3
 59 2018-11-16 23:09:24.967    [INFO]    Thread[Thread-3,5,main] - syncFunTwo before : 3
 60 2018-11-16 23:09:24.967    [INFO]    Thread[Thread-3,5,main] - syncFunTwo after : 4
 61 2018-11-16 23:09:24.967    [INFO]    Thread[Thread-2,5,main] - syncFunTwo before : 4
 62 2018-11-16 23:09:24.967    [INFO]    Thread[Thread-2,5,main] - syncFunTwo after : 5
 63 2018-11-16 23:09:24.967    [INFO]    Thread[Thread-1,5,main] - syncFunTwo before : 5
 64 2018-11-16 23:09:24.967    [INFO]    Thread[Thread-1,5,main] - syncFunTwo after : 6
 65 2018-11-16 23:09:25.018    [INFO]    Thread[Thread-3,5,main] - syncFunTwo before : 6
 66 2018-11-16 23:09:25.018    [INFO]    Thread[Thread-3,5,main] - syncFunTwo after : 7
 67 2018-11-16 23:09:25.018    [INFO]    Thread[Thread-1,5,main] - syncFunTwo before : 7
 68 2018-11-16 23:09:25.018    [INFO]    Thread[Thread-1,5,main] - syncFunTwo after : 8
 69 2018-11-16 23:09:25.018    [INFO]    Thread[Thread-2,5,main] - syncFunTwo before : 8
 70 2018-11-16 23:09:25.018    [INFO]    Thread[Thread-2,5,main] - syncFunTwo after : 9
 71 2018-11-16 23:09:25.018    [INFO]    Thread[Thread-0,5,main] - syncFunTwo before : 9
 72 2018-11-16 23:09:25.018    [INFO]    Thread[Thread-0,5,main] - syncFunTwo after : 10
 73 2018-11-16 23:09:25.019    [INFO]    Thread[Thread-4,5,main] - syncFunTwo before : 10
 74 2018-11-16 23:09:25.019    [INFO]    Thread[Thread-4,5,main] - syncFunTwo after : 11
 75 2018-11-16 23:09:25.069    [INFO]    Thread[Thread-1,5,main] - syncFunTwo before : 11
 76 2018-11-16 23:09:25.069    [INFO]    Thread[Thread-1,5,main] - syncFunTwo after : 12
 77 2018-11-16 23:09:25.069    [INFO]    Thread[Thread-3,5,main] - syncFunTwo before : 12
 78 2018-11-16 23:09:25.069    [INFO]    Thread[Thread-3,5,main] - syncFunTwo after : 13
 79 2018-11-16 23:09:25.069    [INFO]    Thread[Thread-2,5,main] - syncFunTwo before : 13
 80 2018-11-16 23:09:25.069    [INFO]    Thread[Thread-2,5,main] - syncFunTwo after : 14
 81 2018-11-16 23:09:25.070    [INFO]    Thread[Thread-0,5,main] - syncFunTwo before : 14
 82 2018-11-16 23:09:25.070    [INFO]    Thread[Thread-0,5,main] - syncFunTwo after : 15
 83 2018-11-16 23:09:25.070    [INFO]    Thread[Thread-4,5,main] - syncFunTwo before : 15
 84 2018-11-16 23:09:25.070    [INFO]    Thread[Thread-4,5,main] - syncFunTwo after : 16
 85 2018-11-16 23:09:25.120    [INFO]    Thread[Thread-1,5,main] - syncFunTwo before : 16
 86 2018-11-16 23:09:25.120    [INFO]    Thread[Thread-1,5,main] - syncFunTwo after : 17
 87 2018-11-16 23:09:25.120    [INFO]    Thread[Thread-2,5,main] - syncFunTwo before : 17
 88 2018-11-16 23:09:25.120    [INFO]    Thread[Thread-2,5,main] - syncFunTwo after : 18
 89 2018-11-16 23:09:25.120    [INFO]    Thread[Thread-3,5,main] - syncFunTwo before : 18
 90 2018-11-16 23:09:25.120    [INFO]    Thread[Thread-3,5,main] - syncFunTwo after : 19
 91 2018-11-16 23:09:25.121    [INFO]    Thread[Thread-4,5,main] - syncFunTwo before : 19
 92 2018-11-16 23:09:25.121    [INFO]    Thread[Thread-4,5,main] - syncFunTwo after : 20
 93 2018-11-16 23:09:25.121    [INFO]    Thread[Thread-0,5,main] - syncFunTwo before : 20
 94 2018-11-16 23:09:25.121    [INFO]    Thread[Thread-0,5,main] - syncFunTwo after : 21
 95 2018-11-16 23:09:25.171    [INFO]    Thread[Thread-3,5,main] - syncFunTwo before : 21
 96 2018-11-16 23:09:25.171    [INFO]    Thread[Thread-3,5,main] - syncFunTwo after : 22
 97 2018-11-16 23:09:25.171    [INFO]    Thread[Thread-1,5,main] - syncFunTwo before : 22
 98 2018-11-16 23:09:25.171    [INFO]    Thread[Thread-1,5,main] - syncFunTwo after : 23
 99 2018-11-16 23:09:25.171    [INFO]    Thread[Thread-2,5,main] - syncFunTwo before : 23
100 2018-11-16 23:09:25.171    [INFO]    Thread[Thread-2,5,main] - syncFunTwo after : 24
101 2018-11-16 23:09:25.172    [INFO]    Thread[Thread-4,5,main] - syncFunTwo before : 24
102 2018-11-16 23:09:25.172    [INFO]    Thread[Thread-4,5,main] - syncFunTwo after : 25
103 2018-11-16 23:09:25.172    [INFO]    Thread[Thread-0,5,main] - syncFunTwo before : 25
104 2018-11-16 23:09:25.172    [INFO]    Thread[Thread-0,5,main] - syncFunTwo after : 26
105 
106 --------------------測試syncFunThree()的打印結果如下--------------------
107 2018-11-16 23:09:43.712    [INFO]    Thread[Thread-0,5,main] - syncFunThree before : 1
108 2018-11-16 23:09:43.713    [INFO]    Thread[Thread-0,5,main] - syncFunThree after : 2
109 2018-11-16 23:09:43.713    [INFO]    Thread[Thread-4,5,main] - syncFunThree before : 2
110 2018-11-16 23:09:43.713    [INFO]    Thread[Thread-4,5,main] - syncFunThree after : 3
111 2018-11-16 23:09:43.713    [INFO]    Thread[Thread-3,5,main] - syncFunThree before : 3
112 2018-11-16 23:09:43.713    [INFO]    Thread[Thread-3,5,main] - syncFunThree after : 4
113 2018-11-16 23:09:43.714    [INFO]    Thread[Thread-2,5,main] - syncFunThree before : 4
114 2018-11-16 23:09:43.714    [INFO]    Thread[Thread-2,5,main] - syncFunThree after : 5
115 2018-11-16 23:09:43.714    [INFO]    Thread[Thread-1,5,main] - syncFunThree before : 5
116 2018-11-16 23:09:43.714    [INFO]    Thread[Thread-1,5,main] - syncFunThree after : 6
117 2018-11-16 23:09:43.764    [INFO]    Thread[Thread-4,5,main] - syncFunThree before : 6
118 2018-11-16 23:09:43.764    [INFO]    Thread[Thread-4,5,main] - syncFunThree after : 7
119 2018-11-16 23:09:43.764    [INFO]    Thread[Thread-0,5,main] - syncFunThree before : 7
120 2018-11-16 23:09:43.764    [INFO]    Thread[Thread-0,5,main] - syncFunThree after : 8
121 2018-11-16 23:09:43.765    [INFO]    Thread[Thread-1,5,main] - syncFunThree before : 8
122 2018-11-16 23:09:43.765    [INFO]    Thread[Thread-1,5,main] - syncFunThree after : 9
123 2018-11-16 23:09:43.765    [INFO]    Thread[Thread-2,5,main] - syncFunThree before : 9
124 2018-11-16 23:09:43.765    [INFO]    Thread[Thread-2,5,main] - syncFunThree after : 10
125 2018-11-16 23:09:43.765    [INFO]    Thread[Thread-3,5,main] - syncFunThree before : 10
126 2018-11-16 23:09:43.765    [INFO]    Thread[Thread-3,5,main] - syncFunThree after : 11
127 2018-11-16 23:09:43.814    [INFO]    Thread[Thread-4,5,main] - syncFunThree before : 11
128 2018-11-16 23:09:43.814    [INFO]    Thread[Thread-4,5,main] - syncFunThree after : 12
129 2018-11-16 23:09:43.814    [INFO]    Thread[Thread-0,5,main] - syncFunThree before : 12
130 2018-11-16 23:09:43.814    [INFO]    Thread[Thread-0,5,main] - syncFunThree after : 13
131 2018-11-16 23:09:43.815    [INFO]    Thread[Thread-1,5,main] - syncFunThree before : 13
132 2018-11-16 23:09:43.815    [INFO]    Thread[Thread-1,5,main] - syncFunThree after : 14
133 2018-11-16 23:09:43.815    [INFO]    Thread[Thread-3,5,main] - syncFunThree before : 14
134 2018-11-16 23:09:43.815    [INFO]    Thread[Thread-3,5,main] - syncFunThree after : 15
135 2018-11-16 23:09:43.815    [INFO]    Thread[Thread-2,5,main] - syncFunThree before : 15
136 2018-11-16 23:09:43.815    [INFO]    Thread[Thread-2,5,main] - syncFunThree after : 16
137 2018-11-16 23:09:43.865    [INFO]    Thread[Thread-4,5,main] - syncFunThree before : 16
138 2018-11-16 23:09:43.865    [INFO]    Thread[Thread-4,5,main] - syncFunThree after : 17
139 2018-11-16 23:09:43.865    [INFO]    Thread[Thread-0,5,main] - syncFunThree before : 17
140 2018-11-16 23:09:43.865    [INFO]    Thread[Thread-0,5,main] - syncFunThree after : 18
141 2018-11-16 23:09:43.866    [INFO]    Thread[Thread-2,5,main] - syncFunThree before : 18
142 2018-11-16 23:09:43.866    [INFO]    Thread[Thread-2,5,main] - syncFunThree after : 19
143 2018-11-16 23:09:43.866    [INFO]    Thread[Thread-1,5,main] - syncFunThree before : 19
144 2018-11-16 23:09:43.866    [INFO]    Thread[Thread-1,5,main] - syncFunThree after : 20
145 2018-11-16 23:09:43.866    [INFO]    Thread[Thread-3,5,main] - syncFunThree before : 20
146 2018-11-16 23:09:43.866    [INFO]    Thread[Thread-3,5,main] - syncFunThree after : 21
147 2018-11-16 23:09:43.916    [INFO]    Thread[Thread-0,5,main] - syncFunThree before : 21
148 2018-11-16 23:09:43.916    [INFO]    Thread[Thread-0,5,main] - syncFunThree after : 22
149 2018-11-16 23:09:43.916    [INFO]    Thread[Thread-4,5,main] - syncFunThree before : 22
150 2018-11-16 23:09:43.916    [INFO]    Thread[Thread-4,5,main] - syncFunThree after : 23
151 2018-11-16 23:09:43.917    [INFO]    Thread[Thread-1,5,main] - syncFunThree before : 23
152 2018-11-16 23:09:43.917    [INFO]    Thread[Thread-1,5,main] - syncFunThree after : 24
153 2018-11-16 23:09:43.917    [INFO]    Thread[Thread-3,5,main] - syncFunThree before : 24
154 2018-11-16 23:09:43.917    [INFO]    Thread[Thread-3,5,main] - syncFunThree after : 25
155 2018-11-16 23:09:43.917    [INFO]    Thread[Thread-2,5,main] - syncFunThree before : 25
156 2018-11-16 23:09:43.917    [INFO]    Thread[Thread-2,5,main] - syncFunThree after : 26
157 
158 --------------------測試測試wait()和notify()的打印結果如下--------------------
159 2018-11-16 23:10:09.376    [INFO]    Thread[Thread-1,5,main] - syncFunFour2 before : 1
160 2018-11-16 23:10:09.380    [INFO]    Thread[Thread-1,5,main] - syncFunFour2 after : 0
161 2018-11-16 23:10:09.380    [INFO]    Thread[Thread-1,5,main] - sleep beginning.
162 2018-11-16 23:10:09.380    [INFO]    Thread[Thread-0,5,main] - syncFunFour1 before : 0
163 2018-11-16 23:10:09.380    [INFO]    Thread[Thread-0,5,main] - syncFunFour1 after : 1
164 2018-11-16 23:10:12.381    [INFO]    Thread[Thread-1,5,main] - sleep finished.
165 2018-11-16 23:10:12.381    [INFO]    Thread[Thread-1,5,main] - syncFunFour2 before : 1
166 2018-11-16 23:10:12.381    [INFO]    Thread[Thread-1,5,main] - syncFunFour2 after : 0
167 2018-11-16 23:10:12.381    [INFO]    Thread[Thread-1,5,main] - sleep beginning.
168 2018-11-16 23:10:12.381    [INFO]    Thread[Thread-0,5,main] - syncFunFour1 before : 0
169 2018-11-16 23:10:12.381    [INFO]    Thread[Thread-0,5,main] - syncFunFour1 after : 1
170 2018-11-16 23:10:15.382    [INFO]    Thread[Thread-1,5,main] - sleep finished.
171 2018-11-16 23:10:15.382    [INFO]    Thread[Thread-1,5,main] - syncFunFour2 before : 1
172 2018-11-16 23:10:15.382    [INFO]    Thread[Thread-1,5,main] - syncFunFour2 after : 0
173 2018-11-16 23:10:15.382    [INFO]    Thread[Thread-1,5,main] - sleep beginning.
174 2018-11-16 23:10:15.382    [INFO]    Thread[Thread-0,5,main] - syncFunFour1 before : 0
175 2018-11-16 23:10:15.382    [INFO]    Thread[Thread-0,5,main] - syncFunFour1 after : 1
176 2018-11-16 23:10:18.382    [INFO]    Thread[Thread-1,5,main] - sleep finished.
177 2018-11-16 23:10:18.382    [INFO]    Thread[Thread-1,5,main] - syncFunFour2 before : 1
178 2018-11-16 23:10:18.382    [INFO]    Thread[Thread-1,5,main] - syncFunFour2 after : 0
179 2018-11-16 23:10:18.382    [INFO]    Thread[Thread-1,5,main] - sleep beginning.
180 2018-11-16 23:10:18.382    [INFO]    Thread[Thread-0,5,main] - syncFunFour1 before : 0
181 2018-11-16 23:10:18.382    [INFO]    Thread[Thread-0,5,main] - syncFunFour1 after : 1
182 2018-11-16 23:10:21.383    [INFO]    Thread[Thread-1,5,main] - sleep finished.
183 2018-11-16 23:10:21.383    [INFO]    Thread[Thread-1,5,main] - syncFunFour2 before : 1
184 2018-11-16 23:10:21.383    [INFO]    Thread[Thread-1,5,main] - syncFunFour2 after : 0
185 2018-11-16 23:10:21.383    [INFO]    Thread[Thread-1,5,main] - sleep beginning.
186 2018-11-16 23:10:21.383    [INFO]    Thread[Thread-0,5,main] - syncFunFour1 before : 0
187 2018-11-16 23:10:21.383    [INFO]    Thread[Thread-0,5,main] - syncFunFour1 after : 1
188 此處省略...
View Code

 

  二、 ReentrantLock(可重入鎖)和 ReentrantReadWriteLock(讀寫鎖)的用法

      ReentrantLock 是一個樂觀鎖,實現的時候需要手動加鎖和釋放鎖,例如:

  

 1 import java.util.Random;
 2 import java.util.concurrent.*;
 3 
 4 public class MyTest {
 5 
 6     int num = 1; //對num進行逐1累加
 7     final ReentrantLock lock = new ReentrantLock();
 8 
 9     final class MyWork implements Runnable {
10         public void run() {
11             while (true) {
12                 Thread.sleep(new Random().nextInt(2000)+300);
13                 try {
14                     lock.lock();
15                     System.out.println(Thread.currentThread().getName()+" : "+ ++num);
16                 } finally {
17                     lock.unlock();
18                 }
19             }
20         }
21     }
22 
23     public void execute() {
24         ExecutorService executorService = Executors.newFixedThreadPool(5);
25         executorService.submit(new MyWork());
26         executorService.submit(new MyWork());
27         executorService.submit(new MyWork());
28     }
29 }

 

  三、常用的java同步組件

//計數類
java.util.concurrent.CountDownLatch
可用於多線程並發等場景。
構造器:CountDownLatch(int count)
主要方法有:await()、getCount()、countDown()
實現思想是通過unsafe.xxx (Unsafe unsafe = Unsafe.getUnsafe())


//原子類
java.util.concurrent.atomic.AtomicInteger
封裝了原子操作:讀寫數據。
主要構造器有:AtomicInteger(int initialValue)AtomicInteger()

主要方法有:get()set(int newValue)、getAndSet(int newValue)compareAndSet(int expect, int update)、getAndIncrement()、getAndDecrement()
實現思想是通過unsafe.xxx (Unsafe unsafe = Unsafe.getUnsafe()
其他原子類如:AtomicBoolean、AtomicIntegerArray、AtomicLong、AtomicReference<V>等

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM