packagethread;importjava.util.Random;importjava.util.concurrent.Semaphore;importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;classItem {intid;public Item(intid) {this.id =id;
}publicString toString() {return "[item " + id + "]";
}
}abstract classBuffer {intcapacity;
Item[] items;intcount;intin, out;public Buffer(intcapacity) {this.capacity =capacity;
items= newItem[capacity];
count= 0;
in= out = 0;
}abstract voidput(Item item);abstractItem get();public voidprintBuf() {
System.out.print("current buf status: [ ");for (int i = 0; i < capacity; i++) {
System.out.print(items[i]+ " ");
}
System.out.print("] ");
System.out.print("count:" + count + " ");
System.out.print("in:" + in + " out:" + out + " ");
System.out.println();
}
}/*** 利用锁实现线程同步的buffer
*
*@authorjd
**/
class LockBuffer extendsBuffer {
Lock lock= newReentrantLock();
Condition empty=lock.newCondition();
Condition full=lock.newCondition();public LockBuffer(intcapacity) {super(capacity);
}public voidput(Item item) {
lock.lock();try{while (count ==capacity)
full.await();
items[in]=item;
in= (in + 1) %capacity;
count++;
empty.signal();
System.out.println(Thread.currentThread().getName()+ " put item " +item.id);
printBuf();
}catch(InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}publicItem get() {
lock.lock();
Item res= null;try{while (count == 0)
empty.await();
res=items[out];
items[out]= null;
out= (out + 1) %capacity;
count--;
full.signal();
System.out.println(Thread.currentThread().getName()+ " get item " +res.id);
printBuf();
}catch(InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
}returnres;
}
}/*** 利用信号量实现的线程同步的buffer
*
*@authorjd
**/
class SemaphoreBuffer extendsBuffer {
Semaphore mutex;
Semaphore full;
Semaphore empty;public SemaphoreBuffer(intcapacity) {super(capacity);
mutex= new Semaphore(1);
full= new Semaphore(0);
empty= newSemaphore(capacity);
}public voidput(Item item) {try{
empty.acquire();
mutex.acquire();
}catch(InterruptedException e) {
e.printStackTrace();
}
items[in]=item;
in= (in + 1) %capacity;
count++;
System.out.println(Thread.currentThread().getName()+ " put item " +item.id);
printBuf();
mutex.release();
full.release();
}publicItem get() {try{
full.acquire();
mutex.acquire();
}catch(InterruptedException e) {
e.printStackTrace();
}
Item res=items[out];
items[out]= null;
out= (out + 1) %capacity;
count--;
System.out.println(Thread.currentThread().getName()+ " get item " +res.id);
printBuf();
mutex.release();
empty.release();returnres;
}
}/*** 利用同步监视器实现的线程同步的buffer
*
*@authorjd
**/
class MonitorBuffer extendsBuffer {public MonitorBuffer(intcapacity) {super(capacity);
}public voidput(Item item) {synchronized (this) {try{while (count ==capacity)
wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
items[in]=item;
in= (in + 1) %capacity;
count++;
notifyAll();
System.out.println(Thread.currentThread().getName()+ " put item " +item.id);
printBuf();
}
}publicItem get() {synchronized (this) {try{while (count == 0)
wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
Item res=items[out];
items[out]= null;
out= (out + 1) %capacity;
count--;
notifyAll();
System.out.println(Thread.currentThread().getName()+ " get item " +res.id);
printBuf();returnres;
}
}
}class Producer implementsRunnable {
Buffer buf;
Random rand= newRandom();publicProducer(Buffer buf) {this.buf =buf;
}public voidrun() {for (int i = 0; i < 10; i++) {
Item item= new Item(rand.nextInt(100));
buf.put(item);try{
Thread.sleep(500);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}class Consumer implementsRunnable {
Buffer buf;publicConsumer(Buffer buf) {this.buf =buf;
}public voidrun() {for (int i = 0; i < 10; i++) {
Item item=buf.get();try{
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}public classBoundedBufferTest {public static voidmain(String[] args) {//Buffer buf = new LockBuffer(5);//Buffer buf = new SemaphoreBuffer(5);
Buffer buf = new MonitorBuffer(5);//3个生产者,3个消费者,每个生产或者消费10次。
for (int i = 0; i < 3; i++) {new Thread(new Producer(buf), "p" +i).start();new Thread(new Consumer(buf), "c" +i).start();
}
}
}