java多线程—常用并发工具类
CountDownLatch
CountDownLatch
倒计时锁存器
CountDownLatch countDownLatch=newCountDownLatch(3);
await(),进入等待的状态
countDown(),计数器减一
应用场景:启动三个线程计算,需要对结果进行累加。
import java.util.concurrent.CountDownLatch;/**
* @Author: ruan
* Date: 2021/7/6 20:42
* @Description: 倒计时锁存器
*/publicclassTestCountDownLatch{publicstaticvoidmain(String[] args){
CountDownLatch countDownLatch=newCountDownLatch(3);newThread(()->{try{
countDownLatch.await();
System.out.println("计数结束——开始运行");}catch(InterruptedException e){
e.printStackTrace();}}).start();for(int i=0; i<3; i++){int finalI= i;newThread(()->{int j= finalI;try{
Thread.sleep(finalI*1000);
System.out.println(Thread.currentThread().getName()+"就绪");}catch(InterruptedException e){
e.printStackTrace();}finally{
countDownLatch.countDown();}}).start();}}}
CyclicBarrier
- CyclicBarrier
- 栅栏
- 允许一组线程相互等待达到一个公共的障碍点,之后再继续执行
- 跟countDownLatch的区别
- CountDownLatch一般用于某个线程等待若干个其他线程执行完任务之后,它才执行;不可重复使用
- CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;可重用的
import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;/**
* @Author: ruan
* Date: 2021/7/6 17:38
* @Description: 多线程之栅栏
*/publicclassTestCyclicBarrier{publicstaticvoidmain(String[] args){
CyclicBarrier cyclicBarrier=newCyclicBarrier(20,()->{
System.out.println("人满20 发车");});for(int i=0; i<100; i++){newThread(()->{try{
cyclicBarrier.await();}catch(InterruptedException e){
e.printStackTrace();}catch(BrokenBarrierException e){
e.printStackTrace();}}).start();}}}
ReadWriteLock
- ReadWriteLock
- 读写锁
- readLock()读锁可多线程共同读取
- writeLock()写锁获取锁后其他线程无法操作
- 读写锁
import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantLock;import java.util.concurrent.locks.ReentrantReadWriteLock;/**
* @Author: ruan
* Date: 2021/7/6 18:43
* @Description: 读写锁
*/publicclassTestReadWriteLock{static Lock lock=newReentrantLock();staticint value;static ReadWriteLock readWriteLock=newReentrantReadWriteLock();static Lock readLock= readWriteLock.readLock();static Lock writeLock= readWriteLock.writeLock();publicstaticvoidread(Lock lock){try{
lock.lock();
Thread.sleep(1000);
System.out.println("read over!");}catch(InterruptedException e){
e.printStackTrace();}finally{
lock.unlock();}}publicstaticvoidwrite(Lock lock,int v){try{
lock.lock();
Thread.sleep(1000);
value= v;
System.out.println("write over!");}catch(InterruptedException e){
e.printStackTrace();}finally{
lock.unlock();}}publicstaticvoidmain(String[] args){/*for (int i = 0; i < 10; i++) {
new Thread(()->{
read(lock);
}).start();
}
for (int i = 0; i < 2; i++) {
new Thread(()->{
write(lock,2);
}).start();
}*/for(int i=0; i<10; i++){newThread(()->{read(readLock);}).start();}for(int i=0; i<2; i++){newThread(()->{write(writeLock,2);}).start();}}}
Semaphore
Semaphore
信号量
//允许"x"个线程同时进行 Semaphore semaphore=newSemaphore(x);
控制并发数量
使用场景:接口限流
import java.util.concurrent.Semaphore;/**
* @Author: ruan
* Date: 2021/7/6 20:01
* @Description: 信号量
*/publicclassTestSemaphore{publicstaticvoidmain(String[] args){//允许两个线程同时进行
Semaphore semaphore=newSemaphore(1);newThread(()->{try{
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"start");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"end");}catch(InterruptedException e){
e.printStackTrace();}finally{
semaphore.release();}}).start();newThread(()->{try{
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"start");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"end");}catch(InterruptedException e){
e.printStackTrace();}finally{
semaphore.release();}}).start();newThread(()->{try{
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"start");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"end");}catch(InterruptedException e){
e.printStackTrace();}finally{
semaphore.release();}}).start();}}
- 信号量为1(只允许一个线程进行)
- 信号量为2(允许两个个线程进行)
Exchanger
Exchanger
- 数据交换
- 用于交换数据
- 它提供一个同步点,在这个同步点两个线程可以交换彼此的数据。这两个线程通过exchange方法交换数据, 如果第一个线程先执行exchange方法,它会一直等待第二个线程也执行exchange,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方。因此使用Exchanger的重点是成对的线程使用exchange()方法,当有一对线程达到了同步点,就会进行交换数据。因此该工具类的线程对象是【成对】的。
import java.util.concurrent.Exchanger;/**
* @Author: ruan
* Date: 2021/7/6 20:36
* @Description: 数据交换
*/publicclassTestExchanger{publicstaticvoidmain(String[] args){
Exchanger<String> stringExchanger=newExchanger<>();newThread(()->{
String T1="t1";try{
String exchange= stringExchanger.exchange(T1);
System.out.println(Thread.currentThread().getName()+":"+ exchange);}catch(InterruptedException e){
e.printStackTrace();}},"T1").start();newThread(()->{
String T2="t2";try{
String exchange= stringExchanger.exchange(T2);
System.out.println(Thread.currentThread().getName()+":"+ exchange);}catch(InterruptedException e){
e.printStackTrace();}},"T2").start();}}