有A,B,C三个线程,如何保证三个线程同时执行?如何在并发情况下保证三个线程依次执行?如何保证三个线程有序交错执行?
这道面试题,面试官是想问你多线程JUC工具类的CountDownLatch,CylicBarrier,Semaphore
CountDownLatch:
countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行,可保证多条线程同时执行,同时可以模拟高并发下的场景
代码示例:
int size = 3;
//使一个或多个线程等待其他线程各自执行完毕后再执行
//是通过一个计数器来实现的,计数器的初始值是线程的数量,每当一个线程执行完毕后,计数器的值就-1
//,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了.
CountDownLatch countDownLatch = new CountDownLatch(1);
for (int i = 0; i < size; i++) {
new Thread(()->{
try {
//await()方法的线程会被挂起,它会等待直到count值为0才会继续执行
countDownLatch.await();
System.out.println(System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
Thread.sleep(500);
//将count值减1
countDownLatch.countDown();
Semaphore:
Semaphore是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制.使用Semaphore可以控制同时访问资源的线程数,例如,实现一个文件允许的并发访问数.
单信号量下的场景(依次执行):
/**
* 创建Semaphore信号量,初始化许可大小为1
*/
private static Semaphore s1 = new Semaphore(1);
private static Semaphore s2 = new Semaphore(1);
private static Semaphore s3 = new Semaphore(1);
public static void main(String[] args) {
// void acquire():从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断.
// void release();释放一个许可,将其返回给信号量.
// int availablePermits():返回此信号量中当前可用的许可数
// boolean hasQueuedThreads():查询是否有线程正在等待获取
try {
s2.acquire();
s3.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
while (true){
try {
s1.acquire();
Thread.sleep(500);
System.out.println("A");
s2.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(()->{
while (true){
try {
s2.acquire();
Thread.sleep(500);
System.out.println("B");
s3.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(()->{
while (true){
try {
s3.acquire();
Thread.sleep(500);
System.out.println("C");
s1.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}