CountDawnLatch
用 CountDownLatch 控制多个线程同时开始
- 思路: 通过主线程设置 CountDawnLatch 值为 1,其他线程设置 await(),等待count=0, 主线程执行 count.countDown(),唤醒所有等待线程
/**
* 用 CountDownLatch 控制多个线程同时开始
* 思路: 通过主线程设置 CountDawnLatch 值为 1,其他线程设置 await(),等待count=0, 主线程执行 count.countDown(),唤醒所有等待线程
*
*/
public class CountDawnLatchDemo
{
public static void main(String[] args) throws InterruptedException
{
CountDownLatch count = new CountDownLatch(1);
new Thread(new Runnable() {
@Override
public void run()
{
try
{
count.await();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("thread1 结束");
}
}).start();
new Thread(new Runnable()
{
@Override
public void run()
{
try
{
count.await();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
count.countDown();
System.out.println("thread2 结束");
}
}).start();
Thread.sleep(3000);
count.countDown();
}
}
CyclicBarrier
*CyclicBarrier 控制多个线程同时开始
- 思路:CyclicBarrier 设置栅栏解锁条件为 n,启动n个线程,每个线程调用 await(), 直到第n个线程进入栅栏时,才解锁唤醒所有线程
- CyclicBarrier还可以设置解锁后的新任务 , 会选择其中一个线程去执行方法Runable(). 一般选择最后一个进入栅栏的线程
/**
* CyclicBarrier 控制多个线程同时开始
* 思路:CyclicBarrier 设置栅栏解锁条件为 n,启动n个线程,每个线程调用 await(), 直到第n个线程进入栅栏时,才解锁唤醒所有线程
* CyclicBarrier还可以设置解锁后的新任务 , 会选择其中一个线程去执行方法Runable(). 一般选择最后一个进入栅栏的线程
*
*/
public class CyclicBarrierDemo
{
public static void main(String[] args) throws InterruptedException, BrokenBarrierException
{
CyclicBarrier cb = new CyclicBarrier(3, new Runnable()
{
@Override
public void run()
{
System.out.println("被选择处理 action的线程是: " + Thread.currentThread().getName());
System.out.println("action after barrier ");
}
});
new Thread(new Runnable()
{
@Override
public void run()
{
try
{
cb.await(); // 到达屏障,当前线程被阻塞,只有所有需要的线程数量到达屏障后,屏障才会解除,执行
}
catch (InterruptedException | BrokenBarrierException e)
{
e.printStackTrace();
}
System.out.println("thread 1 await over");
}
}, "thread1").start();
Thread.sleep(3000);
Thread t2 = new Thread(new Runnable()
{
@Override
public void run()
{
try
{
cb.await();
Thread.sleep(7000);
System.out.println("当前阻塞的线程数:" + cb.getNumberWaiting());
}
catch (InterruptedException | BrokenBarrierException e)
{
e.printStackTrace();
}
System.out.println("thread 2 await over");
}
}, "thread2");
t2.start();
Thread.sleep(1000);
System.out.println("main: 当前阻塞的线程数:" + cb.getNumberWaiting());
t2.interrupt(); // t2线程处于 await() 时被中断,导致栅栏失效,所有正在栅栏处等待的线程抛出BrokenBarrier异常(t2抛出 中断异常),执行后续的操作
Thread.sleep(100);
System.out.println("main: 当前阻塞的线程数:" + cb.getNumberWaiting());
// 抛出 BrokenBarrierException 异常,终止程序
cb.await();
System.out.println("main over");
}
}
public class CyclicBarrierDemo3
{
public static void main(String[] args) throws InterruptedException, BrokenBarrierException
{
CyclicBarrier cb = new CyclicBarrier(3);
new Thread(new Runner(cb)).start();
Thread.sleep(100);
new Thread(new Runner(cb)).start();
Thread.sleep(2100);
System.out.println(cb.getNumberWaiting()); // 此时线程0 、1 都在处于 await()状态 , 1s 后线程 0 检测到超时,抛出 TimeoutException ,栅栏解除,线程 1 抛出 BrokenBarrierException
Thread.sleep(4000);
System.out.println(cb.getNumberWaiting());
cb.await(); // main 线程抛出 BrokenBarrierException
System.out.println("main over");
}
static class Runner implements Runnable
{
private CyclicBarrier cb;
public Runner(CyclicBarrier cb)
{
this.cb = cb;
}
@Override
public void run()
{
try
{
System.out.println(Thread.currentThread().getName() + "进入");
Thread.sleep(2000);
cb.await(1000, TimeUnit.MILLISECONDS);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch (BrokenBarrierException e)
{
System.out.println("线程" + Thread.currentThread().getName() + "抛出BrokenBarrierException");
e.printStackTrace();
}
catch (TimeoutException e)
{
System.out.println("线程" + Thread.currentThread().getName() + "抛出TimeoutException");
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + " 执行任务");
}
}
}