Semaphore是Java线程的一个计数信号量。我们可用于多线程的并发访问控制。
就像我们常见的线程池,数据库连接池就可以使用Semaphore进行逻辑的实现。Semaphore中我们就介绍两个最常用的两个方法。
acquire() 从Semaphore获取许可,如果计数不小于0,就说明还有可用的许可,那么线程就可以成功获取许可,执行。如果没有许可
了,那么这个方法就会一直阻塞到成功获取许可。默认获取一个许可。
release()
释放许可。当我们使用完毕之后,一定要记得释放许可,以便让其它线程可以继续获取许可访问资源。
示例:
public class SemaphoreTest {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3, true); // 创建信号量,第二个参数表示是公平的还是非公平的
for(int i=1;i<=5;i++){
new Thread(new Producer(semaphore), "线程"+i).start();
}
}
}
class Producer implements Runnable{
private Semaphore semaphore;
public Producer(Semaphore semaphore) {
this.semaphore = semaphore;
}
@Override
public void run() {
try {
semaphore.acquire(); // 这里如果不能获得许可,就会一直阻塞
} catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName()+"producer");
semaphore.release(); // 释放许可
}
}
Exchanger 可以在两个线程之间交换数据,但是也仅仅允许两个线程。
Exchanger有一个exchange()方法,可以接收要交换的数据。当一个线程调用exchange方法之后,就会阻塞,一直到另一个线程也
调用exchange方法,这时两个线程的数据进行交换后,两个线程就得以继续执行了。
方法示例:
// 创建Exchanger实例
Exchanger<String> exchanger = new Exchanger<>();
// 线程1调用Exchanger实例的exchange方法
exchanger.exchange("线程1数据");
// 线程2调用Exchanger实例的exchange方法
exchanger.exchange("线程2数据");
只有当两个线程都调用同一个Exchanger实例的exchange方法后,线程才能得以继续执行。