几种线程等待的基本用法
1.CyclicBarrier
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** * CyclicBarrier 同步屏障 * 1.设置的所有现在都awit后才执行。 * 2.两个构造函数,一个设置的线程个数,一个加同步后的执行 * 3.可以reset,循环使用 * * 实现原理 ReentrantLock+Condition * * 特点: * 1.主线程不等待,子线程await后等待 * 2.可以重复使用 */ public class CyclicBarrierTest { public static void main(String[] args) { CyclicBarrier barrier=new CyclicBarrier(5,()->{ System.out.println("所有线程执行完第一步,开始执行第二步"+Thread.currentThread().getName()); }); for (int i = 0; i < 5; i++) { new Thread(()->{ try { System.out.println(Thread.currentThread().getName()+"开始执行"); barrier.await(); System.out.println(Thread.currentThread().getName()+"执行完"); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }).start(); } System.out.println("主线程执行"); } }
执行结果:
2.CountDownLatch
import java.util.concurrent.CountDownLatch; /** * CountDownLatch 计数的闭锁 * * 特点: * 1.主线程await后等待。 * 2.子线程countDown减一,但不会等待。 * 3.只能执行一次。
共享锁 */ public class CountDownLatchTest { public static void main(String[] args) { CountDownLatch count=new CountDownLatch(5); for (int i = 0; i < 5; i++) { new Thread(()->{ count.countDown(); System.out.println("执行数量:"+count.getCount()); }).start(); } try { count.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("等待完成,去执行"); } }
执行结果:
3.Semaphore
import java.util.Random; import java.util.concurrent.Semaphore; /** * Semaphore:信号量 * 用法: * 1.new Semaphore(5):先设置令牌数量。 * 2.semaphore.acquire():线程先获取令牌,获取到执行,获取不到阻塞。 * 3.semaphore.release():释放令牌,令牌自动放入Semaphore中。 * * 特点:共享锁,限流用途。 * 内部实现:AQS的tryAcquireShared */ public class Park { private int count ; Semaphore semaphore; public Park(int count) { this.count=count; this.semaphore = new Semaphore(count); } public void park(){ try { System.out.println("申请车位:"+Thread.currentThread().getName()); semaphore.acquire(); Random random=new Random(); System.out.println("申请车位成功"+Thread.currentThread().getName()); Thread.sleep(random.nextInt(10)*1000); System.out.println("释放车位"+Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); }finally { semaphore.release(); } } }
import java.util.Random; import java.util.concurrent.Semaphore; /** * */ public class SemaphoreTest { public static void main(String[] args) { Park p=new Park(5); for (int i = 0; i < 8; i++) { new Thread(()->{ p.park(); }).start(); } AtomicTest atomicTest = new AtomicTest(); } }