Java中的信号量(Semaphore)和CountDownLatch是两种常用的同步工具,它们都可以用于控制多个线程之间的并发执行,本文将详细介绍这两种同步工具的使用方法。
信号量(Semaphore)
信号量是一个计数器,用于管理一组资源,它是一个整数变量,表示可用资源的数目,当一个线程需要使用资源时,它会尝试获取信号量,如果信号量的值大于0,那么线程就获得一个资源并继续执行;否则,线程将被阻塞,直到其他线程释放资源。
1、创建信号量
要创建一个信号量,可以使用java.util.concurrent.Semaphore
类,构造函数接受一个整数参数,表示初始可用资源的数量。
import java.util.concurrent.Semaphore; public class SemaphoreExample { public static void main(String[] args) { Semaphore semaphore = new Semaphore(3); // 创建一个初始可用资源为3的信号量 } }
2、获取和释放资源
要获取一个资源,可以使用acquire()
方法,这个方法会阻塞当前线程,直到信号量的值大于0。
semaphore.acquire(); // 获取一个资源
要释放一个资源,可以使用release()
方法,这个方法会增加信号量的值。
semaphore.release(); // 释放一个资源
3、示例
下面是一个使用信号量的示例,它创建了两个线程,分别打印奇数和偶数,我们使用信号量来限制同时访问共享资源的线程数量。
import java.util.concurrent.Semaphore; public class SemaphoreExample { public static void main(String[] args) throws InterruptedException { Semaphore semaphore = new Semaphore(1); // 创建一个初始可用资源为1的信号量 Thread oddThread = new Thread(new PrintOddNumbers(semaphore)); Thread evenThread = new Thread(new PrintEvenNumbers(semaphore)); oddThread.start(); evenThread.start(); oddThread.join(); evenThread.join(); } }
class PrintOddNumbers implements Runnable { private Semaphore semaphore; private int count = 1; public PrintOddNumbers(Semaphore semaphore) { this.semaphore = semaphore; } @Override public void run() { try { semaphore.acquire(); // 获取信号量,确保只有一个线程可以访问共享资源 while (count <= 10) { System.out.println("奇数:" + count); count += 2; semaphore.release(); // 释放信号量,允许其他线程访问共享资源 semaphore.acquire(); // 再次获取信号量,确保只有一个线程可以访问共享资源 } } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); // 最后释放信号量,确保所有线程都可以访问共享资源 } } }
class PrintEvenNumbers implements Runnable { private Semaphore semaphore; private int count = 2; public PrintEvenNumbers(Semaphore semaphore) { this.semaphore = semaphore; } @Override public void run() { try { semaphore.acquire(); // 获取信号量,确保只有一个线程可以访问共享资源 while (count <= 10) { System.out.println("偶数:" + count); count += 2; semaphore.release(); // 释放信号量,允许其他线程访问共享资源 semaphore.acquire(); // 再次获取信号量,确保只有一个线程可以访问共享资源 } } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); // 最后释放信号量,确保所有线程都可以访问共享资源 } } }
CountDownLatch(倒计时锁存器)
CountDownLatch是一个同步辅助类,它允许一个或多个线程等待其他线程完成操作,它的主要方法是countDown()
和await()
。countDown()
方法用于减少倒计时锁存器的计数值,而await()
方法用于等待倒计时锁存器的计数值为0,当计数值为0时,所有等待的线程将被唤醒,倒计时锁存器的计数值只能被初始化一次,且之后不能被重置,如果需要重置计数值,可以创建一个新的倒计时锁存器对象。
1、创建CountDownLatch对象:CountDownLatch(int count)
,其中count
是倒计时锁存器的初始计数值,创建一个初始计数值为3的倒计时锁存器:CountDownLatch countDownLatch = new CountDownLatch(3);
。
原创文章,作者:酷盾叔,如若转载,请注明出处:https://www.kdun.com/ask/294485.html
本网站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本网站。如有问题,请联系客服处理。
发表回复