Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。今天我们就学习一下Semaphore的用法。
java中多线程Semaphore的使用
关于Semaphore常用的方法的介绍
// 从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。
acquire():Acquires a permit from this semaphore, blocking until one is available, or the thread is interrupted.
// 释放一个许可,将其返回给信号量。
release() :Releases a permit, returning it to the semaphore.
一、Semaphore的简单使用
public class SemaphoreTest {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
final Semaphore availableWindow = new Semaphore(5);
int count = 1;
@Override
public void run() {
int time = (int) (Math.random() * 10 + 3);
int num = count++;
try {
availableWindow.acquire();
System.out.println("正在为第【" + num + "】个客户办理业务,需要时间:" + time + "s!");
Thread.sleep(time * 1000);
if (availableWindow.hasQueuedThreads()) {
System.out.println("第【" + num + "】个客户已办理完业务,有请下一位!");
} else {
System.out.println("第【" + num + "】个客户已办理完业务,没有客户了,休息中!");
}
availableWindow.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}; // 循环10次
for (int i = 1; i < 10; i++) {
new Thread(runnable).start();
}
}
}
运行的结果如下:每次运行的结果是不一样的
正在为第【】个客户办理业务,需要时间:3s!
正在为第【】个客户办理业务,需要时间:12s!
正在为第【】个客户办理业务,需要时间:10s!
正在为第【】个客户办理业务,需要时间:7s!
正在为第【】个客户办理业务,需要时间:3s!
第【】个客户已办理完业务,有请下一位!
正在为第【】个客户办理业务,需要时间:11s!
第【】个客户已办理完业务,有请下一位!
正在为第【】个客户办理业务,需要时间:6s!
第【】个客户已办理完业务,有请下一位!
正在为第【】个客户办理业务,需要时间:10s!
第【】个客户已办理完业务,有请下一位!
正在为第【】个客户办理业务,需要时间:12s!
第【】个客户已办理完业务,没有客户了,休息中!
第【】个客户已办理完业务,没有客户了,休息中!
第【】个客户已办理完业务,没有客户了,休息中!
第【】个客户已办理完业务,没有客户了,休息中!
第【】个客户已办理完业务,没有客户了,休息中!
二、Semaphore可以当成mutual exclusion lock使用
A semaphore initialized to one, and which is used such that it only has at most one permit available, can serve as a mutual exclusion lock.
package com.linux.huhx.concurreny; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class SemaphoreTest1 {
public static void main(String[] args) {
final BusinessTask task = new BusinessTask();
ExecutorService service = Executors.newFixedThreadPool(3);
for (int i = 0; i < 3; i++) {
service.execute(task);
}
service.shutdown();
} private static class BusinessTask implements Runnable {
private int count;
Lock lock = new ReentrantLock();
Semaphore semaphore = new Semaphore(1); @Override
public void run() {
try {
// semaphore.acquire();
lock.lock();
count ++;
Thread.sleep(1000);
System.out.println(count);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// semaphore.release();
lock.unlock();
}
}
}
}
运行的结果固定如下: