Semaphore和CountDownLatch实例
直接上代码,记录一下Java并发学习中的线程同步辅助类Semaphore和CountDownLatch使用
package com.petecc.platform.foodsafe.concurrent.semaphore;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @Description 信号量Semaphore测试
* @author tanw
* @date 2015年11月15日 下午8:42:05
*/
public class Main {
public static void main(String[] args) {
int THREAD_SIZE = 10;
//线程结束批示,CountDownLatch只准进入一次,一旦内部计数器到达0,只能重新new
CountDownLatch endLatch = new CountDownLatch(THREAD_SIZE);
Printer printer = new Printer();
Thread[] threads = new Thread[10];
for(int i=0; i<threads.length;i++){
threads[i] = new Thread(new PrintJob(printer,endLatch),"PrintJob"+i);
}
for(int i=0; i<threads.length;i++){
threads[i].start();
}
try {
endLatch.await();//等待所有线程结束
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("It is end in MAIN thread!");
}
}
class PrintJob implements Runnable{
private Printer printer;
private CountDownLatch endLatch;
public PrintJob(Printer printer,CountDownLatch endLatch) {
super();
this.printer = printer;
this.endLatch = endLatch;
}
@Override
public void run() {
String printObj = "doc"+new Random().nextInt(1000);
printer.printJob(printObj);
endLatch.countDown();//完成任务
System.out.printf("%s end print job, endLatch getCount()=%d\n",Thread.currentThread().getName(),endLatch.getCount());
}
}
class Printer{
private Semaphore semaphore; //信号量
private boolean[] freePrinters; //所有可用的打印机
private Lock printlock;
public Printer(){
semaphore = new Semaphore(3);
freePrinters = new boolean[3];
for(int i=0; i<freePrinters.length; i++){
freePrinters[i] = true;
}
printlock = new ReentrantLock();
}
public void printJob(Object obj){
try {
semaphore.acquire();
int printerIdx = getValidPrinter();
System.out.printf("\t\t%s use PRINTER %d print %s\n",Thread.currentThread().getName(),
printerIdx,obj.toString());
long duration = new Random().nextInt(5);
TimeUnit.SECONDS.sleep(duration);
System.out.printf("\t\t%s finish print job in duration %d second\n",Thread.currentThread().getName(),duration);
freePrinters[printerIdx] = true;
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
semaphore.release();
}
}
public int getValidPrinter(){
int ret = -1;
try{
printlock.lock();
for(int i=0; i<freePrinters.length; i++){
if(freePrinters[i]){
ret = i;
freePrinters[i] = false;
break;
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
printlock.unlock();
}
return ret;
}
}