学习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>等

 

posted @ 2020-04-17 17:58  温柔的星空,让你感动  阅读(1096)  评论(0编辑  收藏  举报