實現思路:
- 1.wait、notifyAll實現:
- 2.Samper信號量令牌
- 3.Lock鎖
代碼分別實現這四種
定義一個接口:
IPutGetBlock.java
public interface IPutGetBlock<I> {
void putThread(I i) throws InterruptedException;
I getThread() throws InterruptedException;
}
1.wait、notifyAll實現:
import java.util.LinkedList;
import java.util.List;
public class WaitNotifyBlock<E> implements IPutGetBlock<E>{
private List queue = new LinkedList();
private int limit=0;
public WaitNotifyBlock(int limit) {
this.limit = limit;
}
@Override
public synchronized void putThread(E o) throws InterruptedException {
while (queue.size()>=limit)
wait();
queue.add(o);
notifyAll();
}
@Override
public synchronized E getThread() throws InterruptedException {
while (queue.size()==0)
wait();
E e = (E) queue.remove(0);
notifyAll();
return e;
}
}
2.Samper信號量令牌
com.bruce.chen.part3.ch10.block;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Semaphore;
public class SemphoreBlock<E> implements IPutGetBlock<E> {
private Semaphore items, spaces;
private List queue = new LinkedList<>();
public SemphoreBlock(int items) {
this.spaces = new Semaphore(items);
this.items = new Semaphore(0);
}
@Override
public void putThread(E e) throws InterruptedException {
spaces.acquire();
synchronized (this) {
queue.add(e);
}
items.release();
}
@Override
public E getThread() throws InterruptedException {
items.acquire();
E e;
synchronized (this) {
e = (E) queue.remove(0);
}
spaces.release();
return e;
}
}
3.Lock鎖
LockConditionBlock
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockConditionBlock<E> implements IPutGetBlock<E>{
private List<E> queue = new LinkedList<E>();
private int limit = 2;
private Lock lock = new ReentrantLock();
private Condition notFull = lock.newCondition();
private Condition notEmpty = lock.newCondition();
public LockConditionBlock() {
this(2);
}
public LockConditionBlock(int limit) {
this.limit = limit;
}
@Override
public void putThread(E e) throws InterruptedException {
lock.lock();
try {
while(queue.size()==limit){
notFull.await();
}
queue.add(e);
notEmpty.signal();
}finally {
lock.unlock();
}
}
@Override
public E getThread() throws InterruptedException {
lock.lock();
try {
while (queue.size() == 0) {
notEmpty.await();
}
E e = queue.remove(0);
notFull.signal();
return e;
}finally {
lock.unlock();
}
}
}
test測試:
MyTest.class
public class MyTest {
static class PutThread extends Thread{
private IPutGetBlock<String> iPutGetBlock;
public PutThread(IPutGetBlock<String> iPutGetBlock) {
this.iPutGetBlock = iPutGetBlock;
}
@Override
public void run() {
super.run();
// while (!Thread.currentThread().isInterrupted()){
for (int i = 0; i < 10; i++) {
try {
iPutGetBlock.putThread("i="+i);
System.out.println("生產=i="+i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// }
}
}
static class TaskThread extends Thread{
private IPutGetBlock<String> iPutGetBlock;
public TaskThread(IPutGetBlock<String> iPutGetBlock) {
this.iPutGetBlock = iPutGetBlock;
}
@Override
public void run() {
super.run();
while(!Thread.currentThread().isInterrupted()){
try {
String msg = iPutGetBlock.getThread();
System.out.println("消費="+msg);
} catch (InterruptedException e) {
System.out.println("被中斷!");
break;
}
}
}
}
public static void main(String[] args) {
// IPutGetBlock waitNotifyBlock = new WaitNotifyBlock(5);
// IPutGetBlock waitNotifyBlock = new SemphoreBlock<>(5);
IPutGetBlock waitNotifyBlock = new LockConditionBlock(5);
new PutThread(waitNotifyBlock).start();
new TaskThread(waitNotifyBlock).start();
new TaskThread(waitNotifyBlock).start();
}
}