Semaphore主要的作用時限制併發的線程數,過多的線程會導致cpu資源耗盡,使線程執行任務變緩慢
* Semaphore可用於pool池技術 Semaphore(1,false);非公平鎖,若第二個參數爲true則使公平鎖(與線程啓動有關)
* permits.acquire();獲取信號量 permits.release();釋放信號量
* permits.acquireUninterruptibly();當前線程不可中斷
* permits.availablePermits();獲取當前可用的信號量
* permits.drainPermits();立即獲取當前可用的信號量,並將可用信號量置零
* permits.tryAcquire();嘗試獲取信號量,失敗返回false,成功返回true
* permits.tryAcquire(long time,TimeUnit timeUnit);指定時間嘗試獲取一個信號量
* permits.tryAcquire(int n,long time,TimeUnit timeUnit);指定時間嘗試獲取n個信號量
public class Container {
private Object[] container = new Object[5];
private final int size = container.length;
private final Semaphore set = new Semaphore(5);// 生產者
private final Semaphore get = new Semaphore(5);// 消費者
private final ReentrantLock lock = new ReentrantLock();
private final Condition setCondition = lock.newCondition();// 生產條件
private final Condition getCondition = lock.newCondition();// 消費條件
public boolean isEmpty() {
boolean empty = true;
for (int i = 0; i < size; i++) {
if (container[i] != null) {
empty = false;
break;
}
}
return empty;
}
public boolean isFull() {
boolean full = true;
for (int i = 0; i < size; i++) {
if (container[i] == null) {
full = false;
break;
}
}
return full;
}
public void get() {
get.acquireUninterruptibly();
lock.lock();
while (isEmpty()) {
try {
getCondition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for (int i = 0; i < size; i++) {
if (container[i] != null) {
System.out.println(Thread.currentThread().getName()+" consume " + container[i]);
container[i] = null;
break;
}
}
setCondition.signalAll();
lock.unlock();
get.release();
}
public void set(String str) {
set.acquireUninterruptibly();
lock.lock();
while(isFull()){
try {
setCondition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for (int i = 0; i < size; i++) {
if (container[i] == null) {
System.out.println(Thread.currentThread().getName()+" product " + str);
container[i] = str;
break;
}
}
getCondition.signalAll();
lock.unlock();
set.release();
}
}
public class Consumer extends Thread {
Container c;
Consumer(Container c) {
this.c = c;
}
@Override
public void run() {
while(true){
c.get();
}
}
}
public class Productor extends Thread {
Container c;
Productor(Container c) {
this.c = c;
}
@Override
public void run() {
while (true) {
c.set("data");
}
}
}
public class SemaphoreTest {
public static void main(String[] args) {
Container c = new Container();
for (int i = 0; i < 5; i++) {
new Consumer(c).start();
new Productor(c).start();
}
}
}