学习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 此处省略...
二、 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>等
本文链接:https://www.cnblogs.com/cheng2839
关于博主:评论和私信会在第一时间回复。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!