java多线程之Semaphore

理论

Semaphore:一个可计数的信号量。一般,一个semaphore 信号量是一组许可证。如果必要,那个每次acquire获取许可都是阻塞的,直接一个许可证是可用的,并获取到。每次release释放,都会增加一个许可证,潜在的,也会释放一个阻塞请求。然而。并非每次许可对象都可以被使用的,这个Semaphore信号量只保存几个可用的许可证和相应的操作。

方法

  • Semaphore(int permits): 创建一个指定数量的许可的信号量

  • Semaphore(int permits, boolean fair) 创建一个指定数量的许可,并保证每个线程都是公平的,当fairtrue时,信号量会安装先进先出的原则来获取许可.

  • 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,运行正常,程序中不会发生四个人以及四个以上的人在同时洗澡的情况.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值