14-Java5的Semaphere同步工具

 

范例:模拟一个银行柜台只有3个窗口,有10个客户过来办理业务

package cn.itcast.demo.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class SemaphoreTest {
	public static void main(String[] args) {
		// 创建一个线程池对象
		ExecutorService executorService = Executors.newCachedThreadPool();
		// 创建信号灯数量(即资源的数量,比如只有3个座位)
		final int count = 3;
		//final Semaphore sp = new Semaphore(count);	// 哪个客户先办理业务,是随机叫号的,不公平
		final Semaphore sp = new Semaphore(count, true);	// 先到的客户先办理业务,公平(或者可以设置VIP窗口)
		// 创建10个线程
		for (int i=1; i<=10; i++) {
			Runnable runnable = new Runnable() {
				@Override
				public void run() {
					try {
						// 从信号灯中获取一个许可(即允许一个线程进入)
						sp.acquire();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					System.out.println("线程[ " + Thread.currentThread().getName() + " ]进入,当前已有[ " 
								+ (count-sp.availablePermits()) + " ]个并发");
					
					try {
						Thread.sleep((long)Math.random()*10000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					System.out.println("线程[ " + Thread.currentThread().getName() + " ]即将离开");
					
					// 释放一个信号灯许可,将其返回到信号量
					sp.release();
					
					// 下面的代码有时候执行不准确,因为没有和上面的代码合成原子性
					System.out.println("线程[ " + Thread.currentThread().getName() + " ]已离开,当前已有[ " 
								+ (count-sp.availablePermits()) + " ]个并发");
				}
			};
			// 将任务放入线程池中
			executorService.execute(runnable);
		}
	}
}

 

打印结果:

线程[ pool-1-thread-1 ]进入,当前已有[ 1 ]个并发
线程[ pool-1-thread-5 ]进入,当前已有[ 2 ]个并发
线程[ pool-1-thread-2 ]进入,当前已有[ 3 ]个并发
线程[ pool-1-thread-2 ]即将离开
线程[ pool-1-thread-1 ]即将离开
线程[ pool-1-thread-1 ]已离开,当前已有[ 2 ]个并发
线程[ pool-1-thread-5 ]即将离开
线程[ pool-1-thread-5 ]已离开,当前已有[ 2 ]个并发
线程[ pool-1-thread-9 ]进入,当前已有[ 3 ]个并发
线程[ pool-1-thread-6 ]进入,当前已有[ 2 ]个并发
线程[ pool-1-thread-3 ]进入,当前已有[ 3 ]个并发
线程[ pool-1-thread-2 ]已离开,当前已有[ 3 ]个并发
线程[ pool-1-thread-3 ]即将离开
线程[ pool-1-thread-4 ]进入,当前已有[ 3 ]个并发
线程[ pool-1-thread-3 ]已离开,当前已有[ 3 ]个并发
线程[ pool-1-thread-9 ]即将离开
线程[ pool-1-thread-9 ]已离开,当前已有[ 2 ]个并发
线程[ pool-1-thread-8 ]进入,当前已有[ 3 ]个并发
线程[ pool-1-thread-6 ]即将离开
线程[ pool-1-thread-6 ]已离开,当前已有[ 2 ]个并发
线程[ pool-1-thread-7 ]进入,当前已有[ 3 ]个并发
线程[ pool-1-thread-4 ]即将离开
线程[ pool-1-thread-4 ]已离开,当前已有[ 2 ]个并发
线程[ pool-1-thread-10 ]进入,当前已有[ 3 ]个并发
线程[ pool-1-thread-8 ]即将离开
线程[ pool-1-thread-8 ]已离开,当前已有[ 2 ]个并发
线程[ pool-1-thread-7 ]即将离开
线程[ pool-1-thread-7 ]已离开,当前已有[ 1 ]个并发
线程[ pool-1-thread-10 ]即将离开
线程[ pool-1-thread-10 ]已离开,当前已有[ 0 ]个并发

 

以上结果不准确,需修改代码,合成原子性

 

posted @ 2017-08-17 22:32  半生戎马,共话桑麻、  阅读(166)  评论(0)    收藏  举报
levels of contents