理论
Semaphore
:一个可计数的信号量。一般,一个semaphore
信号量是一组许可证。如果必要,那个每次acquire
获取许可都是阻塞的,直接一个许可证是可用的,并获取到。每次release
释放,都会增加一个许可证,潜在的,也会释放一个阻塞请求。然而。并非每次许可对象都可以被使用的,这个Semaphore
信号量只保存几个可用的许可证和相应的操作。
方法
-
Semaphore(int permits)
: 创建一个指定数量的许可的信号量 -
Semaphore(int permits, boolean fair)
创建一个指定数量的许可,并保证每个线程都是公平的,当fair
为true
时,信号量会安装先进先出的原则来获取许可. -
acquire()
在当前信号量中获取一个许可.当前线程会一直阻塞直到有一个可用的许可,或被其他线程中断. -
release()
释放一个许可,把让它返回到这个信号量中.
例子
举小明
和小红
谈人生和理想的例子.之前他们在卧室里谈了好几百毫秒的人生和理想.顿时都感觉身疲惫,感觉身体好像被掏空了一样.所以这里他们都想洗一个热水澡,但是沐浴室只有三间,那就抢吧..ok,开始编程...
package cn.day15;
import java.util.concurrent.Semaphore;
public class ShowerRoom {
private static final int MAX_SIZE = 3;
Semaphore semaphore = new Semaphore(MAX_SIZE);
public void bathe(String name){
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " 洗唰唰啊..洗唰唰... ");
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println(Thread.currentThread().getName() + " 终于洗完澡了...");
semaphore.release();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
BoyAndGril类
package cn.day15;
public class BoyAndGril implements Runnable {
ShowerRoom showerRoom;
public BoyAndGril(ShowerRoom showerRoom) {
this.showerRoom = showerRoom;
}
public void run() {
// TODO Auto-generated method stub
String name = Thread.currentThread().getName();
showerRoom.bathe(name);
}
}
TestMain测试类
package cn.day15;
import java.util.HashSet;
import java.util.Set;
public class TestMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<Thread> boyAndGril = new HashSet<Thread>();
ShowerRoom showerRoom = new ShowerRoom();
for (int i = 0; i < 10; i ++){
boyAndGril.add(new Thread(new BoyAndGril(showerRoom), "小明" + i + "号"));
}
for (int i = 0; i < 10; i ++){
boyAndGril.add(new Thread(new BoyAndGril(showerRoom), "小红" + i + "号"));
}
for (Thread thread : boyAndGril){
thread.start();
}
}
}
运行结果:
小明3号 洗唰唰啊..洗唰唰...
小明5号 洗唰唰啊..洗唰唰...
小明4号 洗唰唰啊..洗唰唰...
小明4号 终于洗完澡了...
小明3号 终于洗完澡了...
小红7号 洗唰唰啊..洗唰唰...
小明5号 终于洗完澡了...
小红1号 洗唰唰啊..洗唰唰...
小红3号 洗唰唰啊..洗唰唰...
小红7号 终于洗完澡了...
小红1号 终于洗完澡了...
小明7号 洗唰唰啊..洗唰唰...
小红3号 终于洗完澡了...
小红9号 洗唰唰啊..洗唰唰...
小红6号 洗唰唰啊..洗唰唰...
小红9号 终于洗完澡了...
小明7号 终于洗完澡了...
小红4号 洗唰唰啊..洗唰唰...
小红6号 终于洗完澡了...
小明9号 洗唰唰啊..洗唰唰...
小明2号 洗唰唰啊..洗唰唰...
小红4号 终于洗完澡了...
小红5号 洗唰唰啊..洗唰唰...
小明2号 终于洗完澡了...
小明9号 终于洗完澡了...
小明1号 洗唰唰啊..洗唰唰...
小红0号 洗唰唰啊..洗唰唰...
小红5号 终于洗完澡了...
小红2号 洗唰唰啊..洗唰唰...
小明1号 终于洗完澡了...
小明8号 洗唰唰啊..洗唰唰...
小红0号 终于洗完澡了...
小明0号 洗唰唰啊..洗唰唰...
小红2号 终于洗完澡了...
小明6号 洗唰唰啊..洗唰唰...
小明8号 终于洗完澡了...
小红8号 洗唰唰啊..洗唰唰...
小明0号 终于洗完澡了...
小明6号 终于洗完澡了...
小红8号 终于洗完澡了...
ok,运行正常,程序中不会发生四个人以及四个以上的人在同时洗澡的情况.