`
fanshaohua110
  • 浏览: 7156 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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);
	}

}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics