java多线程—常用并发工具类
CountDownLatch
-
CountDownLatch
-
倒计时锁存器
-
CountDownLatch countDownLatch = new CountDownLatch(3);
-
await(),进入等待的状态
-
countDown(),计数器减一
-
应用场景:启动三个线程计算,需要对结果进行累加。
-
import java.util.concurrent.CountDownLatch;
/**
* @Author: ruan
* Date: 2021/7/6 20:42
* @Description: 倒计时锁存器
*/
public class TestCountDownLatch {
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(3);
new Thread(()->{
try {
countDownLatch.await();
System.out.println("计数结束——开始运行");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
for (int i = 0; i < 3; i++) {
int finalI = i;
new Thread(()->{
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: 多线程之栅栏
*/
public class TestCyclicBarrier {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(20,()->{
System.out.println("人满20 发车");
});
for (int i = 0; i < 100; i++) {
new Thread(()->{
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: 读写锁
*/
public class TestReadWriteLock {
static Lock lock = new ReentrantLock();
static int value;
static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
static Lock readLock = readWriteLock.readLock();
static Lock writeLock = readWriteLock.writeLock();
public static void read(Lock lock){
try {
lock.lock();
Thread.sleep(1000);
System.out.println("read over!");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public static void write(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();
}
}
public static void main(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++) {
new Thread(()->{
read(readLock);
}).start();
}
for (int i = 0; i < 2; i++) {
new Thread(()->{
write(writeLock,2);
}).start();
}
}
}
Semaphore
-
Semaphore
-
信号量
-
//允许"x"个线程同时进行 Semaphore semaphore = new Semaphore(x);
-
控制并发数量
-
使用场景:接口限流
-
import java.util.concurrent.Semaphore;
/**
* @Author: ruan
* Date: 2021/7/6 20:01
* @Description: 信号量
*/
public class TestSemaphore {
public static void main(String[] args) {
//允许两个线程同时进行
Semaphore semaphore = new Semaphore(1);
new Thread(()->{
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();
new Thread(()->{
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();
new Thread(()->{
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: 数据交换
*/
public class TestExchanger {
public static void main(String[] args) {
Exchanger<String> stringExchanger = new Exchanger<>();
new Thread(()->{
String T1 = "t1";
try {
String exchange = stringExchanger.exchange(T1);
System.out.println(Thread.currentThread().getName() + ":" + exchange);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"T1").start();
new Thread(()->{
String T2 = "t2";
try {
String exchange = stringExchanger.exchange(T2);
System.out.println(Thread.currentThread().getName() + ":" + exchange);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"T2").start();
}
}