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