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