zoukankan      html  css  js  c++  java
  • 学习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>等
    ____________________________特此,勉励____________________________
    本文作者cheng2839
    本文链接https://www.cnblogs.com/cheng2839
    关于博主:评论和私信会在第一时间回复。
    版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
    声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
  • 相关阅读:
    《程序员修炼之道:从小工到专家》阅读笔记02
    第二阶段团队冲刺10
    第二阶段团队冲刺09
    周总结
    第二阶段团队冲刺08
    第二阶段团队冲刺07
    小A和小B和幽灵追两人(双向BFS)
    C. 真假亚瑟王(暴力)
    小A的柱状图(栈的应用,找左右边界)
    小A买彩票
  • 原文地址:https://www.cnblogs.com/cheng2839/p/12721519.html
Copyright © 2011-2022 走看看