java 信号灯 Semaphore

更多介绍 http://blog.csdn.net/java2000_wl/article/details/23556859

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

/**
 * 信号灯  控制并发访问数量  
 * 只有 获取运行令牌(信号灯)后 ,才可以运行,当令牌(信号灯)使用完了,后面的访问 只能等着.直到有令牌被释放后,获取令牌才可以继续访问
 */
public class SemaphoreTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ExecutorService service=Executors.newCachedThreadPool();
		final Semaphore sp=new Semaphore(3,true);  //先进来的先执行
		
		for (int i = 0; i < 10; i++) {
			
			Runnable runnable=new Runnable() {
				
				@Override
				public void run() {
					try {
						sp.acquire();//获取通行证
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} 
					System.out.println("线程"+Thread.currentThread().getName()+"进入,当前已有"+(3-sp.availablePermits())+"个并发");
					
					try {
						//System.out.println(new Random().nextLong());
						Thread.sleep(1000);
					} catch (Exception e) {
						// TODO: handle exception
					}
					System.out.println("线程"+Thread.currentThread().getName()+"即将离开");
					sp.release();
					System.out.println("线程"+Thread.currentThread().getName()+"已离开,当前已有"+(3-sp.availablePermits())+"个并发");
				}
			};
			service.execute(runnable);
		}
		
	}

}

实用场景:
Semaphore 分为单值和多值两种,前者只能被一个线程获得,后者可以被若干个线程获得。
     以一个停车场运作为例。为了简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆不受阻碍的进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入一辆,如果又离开两辆,则又可以放入两辆,如此往复。


下面是模拟一个连接池,控制同一时间最多只能有50个线程访问。
import java.util.UUID;  
import java.util.concurrent.Semaphore;  
import java.util.concurrent.TimeUnit;  
  
public class TestSemaphore extends Thread {  
    public static void main(String[] args) {  
        int i = 0;  
        while (i < 500) {  
            i++;  
            new TestSemaphore().start();  
            try {  
                Thread.sleep(1);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
  
    /** 
     * 控制某资源同时被访问的个数的类 控制同一时间最后只能有50个访问 
     */  
    static Semaphore semaphore = new Semaphore(50);  
    static int timeout = 500;  
  
    public void run() {  
        try {  
            Object connec = getConnection();  
            System.out.println("获得一个连接" + connec);  
            Thread.sleep(300);  
            releaseConnection(connec);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
    }  
  
    public void releaseConnection(Object connec) {  
        /* 释放许可 */  
        semaphore.release();  
        System.out.println("释放一个连接" + connec);  
    }  
  
    public Object getConnection() {  
        try {/* 获取许可 */  
            boolean getAccquire = semaphore.tryAcquire(timeout, TimeUnit.MILLISECONDS);  
            if (getAccquire) {  
                return UUID.randomUUID().toString();  
            }  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        throw new IllegalArgumentException("timeout");  
    }  
} 





猜你喜欢

转载自takeme.iteye.com/blog/2315404