第一种方案:使用CountDownLatch工具类
CountDownLatch:是Java多线程编程中的一个同步工具类(计数锁),它允许一个或多个线程等待其他线程完成操作后再继续执行。其内部维护了一个计数器,当线程在执行任务完成后调用countDown()
方法,该方法会将计数器的值减一,而等待线程通过调用await()
方法来等待计数器的值变为0后才执行。
设计实现
//设计线程类public class ThreadA implements Runnable {//定时锁private CountDownLatch latch;//初始化public ThreadA(CountDownLatch latch){this.latch=latch;}@Overridepublic void run() {//1.执行System.out.println("A线程执行");//2.计数减1latch.countDown();}
}public class ThreadB implements Runnable {//两个定时锁(上一个线程和当前线程)private CountDownLatch latch1;private CountDownLatch latch2;//初始化public ThreadB(CountDownLatch latch1,CountDownLatch latch2){this.latch1=latch1;this.latch2=latch2;}@Overridepublic void run() {try {//1.等待上一个线程执行完成latch1.await();//2.执行System.out.println("B线程执行");//3.计数减1latch2.countDown();} catch (InterruptedException e) {e.printStackTrace();}}
}public class ThreadC implements Runnable {//定时锁private CountDownLatch latch;//初始化public ThreadC(CountDownLatch latch){this.latch=latch;}@Overridepublic void run() {try {//1.等待latch.await();//2.执行System.out.println("C线程执行");} catch (InterruptedException e) {e.printStackTrace();}}
}//测试线程A、B、C顺序执行
public class Main {public static void main(String[] args) {//创建线程A,B的定时锁,计数为1CountDownLatch latchA=new CountDownLatch(1);CountDownLatch latchB=new CountDownLatch(1);//创建线程A、B、CThread a = new Thread(new ThreadA(latchA));Thread b = new Thread(new ThreadB(latchA,latchB));Thread c = new Thread(new ThreadC(latchB));//a,b,c顺序执行a.start();b.start();c.start();}
}
第二种方案:使用Semaphore同步工具
Semaphore(信号量):是一种控制并发访问资源的同步工具,用来限制同时访问某个资源的线程数量。Semaphore内部维护一个计数器,该计数器用于表示可用的许可证数量。线程在访问资源之前必须先通过acquire()方法获得许可证,如果许可证数量为0,则线程必须等待,直到有其他线程释放许可证。当线程使用完资源后,使用release()方法释放许可证,以便其他线程可以继续访问资源。
(实现原理和上个方案思想相同)
第三种方案:使用wait()、notify()
和notifyAll()方法
wait()
方法:使当前线程进入等待状态
notify()
方法:唤醒在相同对象上调用 wait()
方法进入等待状态的线程中的一个线程。
notifyAll()
方法:唤醒在相同对象上调用 wait()
方法进入等待状态的所有线程(只有一个线程会获得(抢到)对象锁,其余线程将继续等待锁的释放)。
class Main {static Object lock = new Object();//对象锁static int threadId = 1;//当前执行线程标志public static void main(String[] args) {//线程A、B、C的标志分别为1,2,3//创建三个线程Thread a = new Thread(new Runnable() {@Overridepublic void run() {try {//获取对象锁synchronized (lock) {//没有到当前线程执行,则释放锁进入等待状态while (threadId != 1) {lock.wait();}//轮到当前线程执行System.out.println("线程A执行");threadId = 2;lock.notifyAll();}} catch (InterruptedException e) {e.printStackTrace();}}});Thread b = new Thread(new Runnable() {@Overridepublic void run() {try {synchronized (lock) {while (threadId != 2) {lock.wait();}System.out.println("线程B执行");threadId = 3;lock.notifyAll();}} catch (InterruptedException e) {e.printStackTrace();}}});Thread c = new Thread(new Runnable() {@Overridepublic void run() {try {synchronized (lock) {while (threadId != 3) {lock.wait();}System.out.println("线程C执行");threadId = 1;lock.notifyAll();}} catch (InterruptedException e) {e.printStackTrace();}}});// 线程顺序执行a.start();b.start();c.start();}
}