四大工具类详讲

多线程

四大工具类

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开始恢复执行

你可能感兴趣的:(Java)