网站站群建设进度,钦州市建设工程质量监督站网站,做二手家电网站怎样,网页设计及网站建设的相关概念文章目录 CountDownLatch、CyclicBarrier、Semaphore 的原理以及实例总结一、CountDownLatch二、CyclicBarrier三、Semaphore总结 CountDownLatch、CyclicBarrier、Semaphore 的原理以及实例总结
在Java多线程编程中#xff0c;有三种常见的同步工具类#xff1a;CountDownL… 文章目录 CountDownLatch、CyclicBarrier、Semaphore 的原理以及实例总结一、CountDownLatch二、CyclicBarrier三、Semaphore总结 CountDownLatch、CyclicBarrier、Semaphore 的原理以及实例总结
在Java多线程编程中有三种常见的同步工具类CountDownLatch、CyclicBarrier、Semaphore。这些工具类使得我们可以在多个线程之间进行协调实现更高效的并发处理。本文将对它们的原理和实例进行分析总结。
一、CountDownLatch
CountDownLatch是一个计数器类用来控制线程等待其他线程执行完毕再继续执行。这个类通常用于主线程等待多个子线程完成任务后再进行下一步操作。CountDownLatch的实现基于AQSAbstractQueuedSynchronizer使用了共享锁的方式。
CountDownLatch的使用思路比较简单首先创建一个CountDownLatch对象并把需要等待的线程数量传入CountDownLatch的构造方法。然后在每个子线程完成任务时通过countDown()方法来减少计数器的值。当计数器变为0时await()方法会返回主线程就可以继续执行下一步操作。
下面是一个简单的示例代码
public class CountDownLatchDemo {public static void main(String[] args) throws InterruptedException {int threadCount 5;CountDownLatch countDownLatch new CountDownLatch(threadCount);for (int i 0; i threadCount ; i) {new Thread(() - {try {Thread.sleep(1000L);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() 执行完毕);countDownLatch.countDown();}).start();}countDownLatch.await();System.out.println(所有线程执行完毕);}
}以上代码中我们创建了一个CountDownLatch对象并传入需要等待的线程数量。然后通过for循环创建了5个子线程每个子线程都会睡眠1秒钟模拟执行任务。当每个子线程完成任务后调用countDown()方法来减少计数器的值。最后在主线程中调用await()方法来等待所有子线程完成任务。
二、CyclicBarrier
CyclicBarrier也是一个很有用的同步工具类它可以让一组线程到达某个屏障也可以理解为关卡时被阻塞直到所有线程都到达该屏障时才能继续执行。CyclicBarrier和CountDownLatch的区别在于CountDownLatch只能使用一次而CyclicBarrier可以重复使用。
CyclicBarrier的实现也是基于AQSAbstractQueuedSynchronizer但是使用了独占锁的方式。CyclicBarrier的使用思路也比较简单首先创建一个CyclicBarrier对象并把需要等待的线程数量和到达该屏障时需要执行的动作可选传入CyclicBarrier的构造方法。当所有线程到达该屏障时CyclicBarrier会自动调用之前设置的动作如果有然后所有线程就可以继续执行接下来的操作。
下面是一个简单的示例代码
public class CyclicBarrierDemo {public static void main(String[] args) throws InterruptedException, BrokenBarrierException {int threadCount 3;CyclicBarrier cyclicBarrier new CyclicBarrier(threadCount, () - System.out.println(所有线程到达屏障));for (int i 0; i threadCount ; i) {new Thread(() - {try {Thread.sleep(1000L);System.out.println(Thread.currentThread().getName() 到达屏障);cyclicBarrier.await();System.out.println(Thread.currentThread().getName() 继续执行);} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}}).start();}}
}以上代码中我们创建了一个CyclicBarrier对象并传入需要等待的线程数量和到达屏障时需要执行的动作。然后通过for循环创建了3个子线程每个子线程都会睡眠1秒钟并在到达屏障时调用await()方法。当所有子线程都到达屏障时CyclicBarrier会自动执行之前设置的动作输出“所有线程到达屏障”然后所有线程就可以继续执行接下来的操作。
三、Semaphore
Semaphore是另一种常见的同步工具类它可以限制同时访问某个共享资源的线程数量。Semaphore的实现也是基于AQSAbstractQueuedSynchronizer使用了共享锁的方式。
Semaphore的使用思路比较简单首先创建一个Semaphore对象并把该共享资源的数量传入Semaphore的构造方法。然后在每个需要访问该共享资源的线程中调用acquire()方法来获取访问权限在使用完共享资源后再调用release()方法来释放访问权限。
下面是一个简单的示例代码
public class SemaphoreDemo {public static void main(String[] args) {int threadCount 10;Semaphore semaphore new Semaphore(2);for (int i 0; i threadCount ; i) {new Thread(() - {try {semaphore.acquire();System.out.println(Thread.currentThread().getName() 获取访问权限);Thread.sleep(1000L);} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();System.out.println(Thread.currentThread().getName() 释放访问权限);}}).start();}}
}以上代码中我们创建了一个Semaphore对象并传入该共享资源的数量。然后通过for循环创建了10个子线程每个子线程需要获取访问权限才能执行如果访问权限已满则需要等待其他线程释放访问权限。当使用完共享资源后子线程需要调用release()方法来释放访问权限。
总结
本文分析了CountDownLatch、CyclicBarrier、Semaphore三种常见的同步工具类的原理和实例。这些工具类可以帮助我们在多个线程之间进行协调实现更高效的并发编程。在使用这些工具类时需要注意不同工具类的区别和使用场景以及合理地控制线程的数量和访问权限避免出现死锁等问题。