JAVA中Semaphore(信号量)

Semaphore :一种可以控制访问资源的数量、或者控制同时同一操作的数量。
Semaphore构造器:
public Semaphore(int permits) 需要传入一个正整数,此数量即为控制访问的资源数量。
public Semaphore(int permits, boolean fair) 创建一个是否是公平的信号量。当fair=true
时,线程将会按到达的顺序(FIFO)执行。
下面是Semaphore的方法.
acquire() 获取一个许可.当获取后对许可集减去1
acquire(int permits) 获取permits个许可,当获取后对许可集减去permits
release() 释放一个许可
release(int permits) 释放permits个许可
acquireUninterruptibly() 一个不可中断的获取一个许可
acquireUninterruptibly(int permits) 一个不可中断的获取permits个许可
tryAcquire() 试图获取一个许可。如果获取到返回true,否则返回false
tryAcquire(int permits) 试图获取permits个许可。如果获取到返回true,否则返回false
tryAcquire(long timeout, TimeUnit unit) 单位时间内,试图获取一个许可。如果获取到返回true,否则返回false
tryAcquire(int permits, long timeout, TimeUnit unit) 单位时间内,试图获取permits个许可。如果获取到返回true,否则返回false


下面举例说下用法:
1.控制访问数量

package com.asiainfo.concurrent;

import java.util.concurrent.Semaphore;

/**
 * Semaphore 是控制资源的访问数量、或者同时执行同一操作的数量.
 * 
 * 假设我们现在手上只有5台电脑,有10个人想上网。因此只能等有的人不上网了,其他人才有机会上网
 * @author fansh
 *
 */
public class SemaphoreTest {
	
	/**
	 * 特定的资源 ---------只有5台电脑
	 */
	private static Semaphore semaphore = new Semaphore(5);
	
	public static void main(String[] args) {
		SemaphoreTest test = new SemaphoreTest();
		for(int i=0;i<10;i++){
			Person person  = test.new Person(i+"");
			person.start();
		}
	}
	
	class Person extends Thread{
		private String name;
		public Person(String name){
			this.name=name;
		}
		public void run() {
			try {
				semaphore.acquire();
				System.out.println(this.name+"正在上网中.....");
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}finally{
				System.out.println(this.name+"不上网中.....");
				semaphore.release();
			}
		}
	}
	

}


2.使无界队列变为有界队列
package com.asiainfo.concurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;

/**
 * Semaphore 
 * 
 * 使无界队列变为有界队列
 * @author fansh
 *
 */
public class SemaphoreTest1<T> {
	private final Semaphore semaphore;
	private final List<T> list = new ArrayList<T>();
	
	public SemaphoreTest1(int bound){
		semaphore= new Semaphore(bound);
	}
	
	public void add(T t){
		try {
			semaphore.acquire();
			list.add(t);
		} catch (InterruptedException e) {
			semaphore.release();
		}
	}
	
	public void remove(T t){
		boolean flag=list.remove(t);
		if(flag){
			semaphore.release();
		}
	}

}


3. 获取许可被中断 和不可中断的用法

package com.asiainfo.concurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;

/**
 * Semaphore 
 * 模拟acquire阻塞时候被中断
 * acquire 抛出InterruptedException 因此是可中断的
 * acquireUninterruptibly 不可中断
 * 
 * @author fansh
 *
 */
public class SemaphoreTest2<T> {
	private final Semaphore semaphore;
	private final List<T> list = new ArrayList<T>();
	
	public SemaphoreTest2(int bound){
		semaphore= new Semaphore(bound);
	}
	
	public void add(T t){
//		try {
//			semaphore.acquire();
//			list.add(t);
//		} catch (InterruptedException e) {
//			System.out.println("添加动作被中断了...........");
//			semaphore.release();
//		}
		// 不可中断测试.....
		semaphore.acquireUninterruptibly();
		list.add(t);
		
	}
	
	public void remove(T t){
		boolean flag=list.remove(t);
		if(flag){
			semaphore.release();
		}
	}
	
	public static void main(String[] args) {
		
		ExecutorService service = Executors.newSingleThreadExecutor();
	    Future future=service.submit(new Runnable() {
			@Override
			public void run() {
				SemaphoreTest2 test2 =new SemaphoreTest2(2);
				test2.add("a");
				test2.add("b");
				test2.add("c");
			}
		});
	    service.shutdown();
	    /**
	     * 等待添加动作充分完成
	     */
	    try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	    future.cancel(true);
	}

}

猜你喜欢

转载自fanshaohua110.iteye.com/blog/2219947