Semaphore :一种可以控制访问资源的数量、或者控制同时同一操作的数量。
Semaphore构造器:
public Semaphore(int permits) 需要传入一个正整数,此数量即为控制访问的资源数量。
public Semaphore(int permits, boolean fair) 创建一个是否是公平的信号量。当fair=true
时,线程将会按到达的顺序(FIFO)执行。
下面是Semaphore的方法.
[table]
|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
||
[/table]
下面举例说下用法:
1.控制访问数量
2.使无界队列变为有界队列
3. 获取许可被中断 和不可中断的用法
Semaphore构造器:
public Semaphore(int permits) 需要传入一个正整数,此数量即为控制访问的资源数量。
public Semaphore(int permits, boolean fair) 创建一个是否是公平的信号量。当fair=true
时,线程将会按到达的顺序(FIFO)执行。
下面是Semaphore的方法.
[table]
|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
||
[/table]
下面举例说下用法:
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);
}
}