多线程
四大工具类
1.CountDownLatch–闭锁
package JUC_Tools;
/**
* 应用场景:运动员跑步比赛时,裁判手里的秒表一定是在运动员都到达终点时候才停止
* 这时候,我们可以假设裁判为主线程,运动员为子线程,即当所有子线程执行结束之后主线成才可以结束
* 四大工具类--闭锁--CountDownLatch
* 每个CountDownLatch对象的计数器减为0时不可以在恢复原值
* 调用await()方法的线程会一直阻塞,直到其他线程执行完毕,也就是CountDownLatch的计数器减为0
* public CountDownLatch(int count)-->传入计数器
* countDown() 减去计数器的方法
*/
import java.util.concurrent.CountDownLatch;
class CountDown implements Runnable{
//传入CountDownLatch对象
private CountDownLatch countDownLatch;
public CountDown(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在执行任务");
//此方法为减去计数器的方法
countDownLatch.countDown();
}
}
public class CountDownLatchTest {
public static void main(String[] args) {
//启动三个子线程,假设为三个运动员
CountDownLatch countDownLatch = new CountDownLatch(3);
Thread thread1 = new Thread(new CountDown(countDownLatch),"A");
thread1.start();
Thread thread2 = new Thread(new CountDown(countDownLatch),"B");
thread2.start();
Thread thread3 = new Thread(new CountDown(countDownLatch),"C");
thread3.start();
try {
//调用await()方法的线程,会一直阻塞,直到计数器减为0
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("所有子线程执行任务结束");
}
}
** 输出结果:**
A正在执行任务
C正在执行任务
B正在执行任务
所有子线程执行任务结束
2.CyclicBarrier–循环栅栏
package JUC_Tools;
import java.sql.Time;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
/**
* 工具类--循环栅栏-->CyclicBarrier
* 循环:每个CyclicBarrier对象的计数器可以重复使用,其中的几个重要方法使用
*
* public CycliBarrier(int count,Runnable barrierAction)-->
* 所有子线程在调用await()方法后将计数器减为0,任意挑选一个线程执行barrierAction任务
*
* public int await() throws InterruptedException, BrokenBarrierException
* 子线程调用await()方法,会进入阻塞状态,并且每当一个子线程调用,CyclicBarrier对象的计数器
* 减一,直到减为0时,所有子线程恢复执行
*/
class Cyclic implements Runnable{
private CyclicBarrier cyclicBarrier;
public Cyclic(CyclicBarrier cyclicBarrier){
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在写入数据");
try {
TimeUnit.SECONDS.sleep(2);
//相当于一堵墙,每个线程执行到此时,会被阻塞
cyclicBarrier.await();
System.out.println("所有线程写入数据完毕"+Thread.currentThread().getName()+"开始恢复执行");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
public class CyclicBarrierTest {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {
@Override
public void run() {
System.out.println("当前线程为"+Thread.currentThread().getName());
}
});
//启动三个线程
for (int i = 0; i < 3; i++){
new Thread(new Cyclic(cyclicBarrier),"写入线程"+i).start();
}
}
}
执行结果:
写入线程0正在写入数据
写入线程1正在写入数据
写入线程2正在写入数据
当前线程为写入线程1
所有线程写入数据完毕写入线程1开始恢复执行
所有线程写入数据完毕写入线程2开始恢复执行
所有线程写入数据完毕写入线程0开始恢复执行