先来看下例子,这个例子中明显能看出问题代码如下:
package com.testredis;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;
public class TestBlockingQueue {
private AtomicInteger counter = new AtomicInteger();
private int minSize = 1;
private int maxSize = 20;
private List<Object> mq = new ArrayList();
private final Object lock = new Object();
public TestBlockingQueue(int minSize,int maxSize){
this.minSize = minSize;
this.maxSize = maxSize;
}
public void put(Object object){
synchronized (lock){
//if (this.counter.get() >= maxSize){ 错误代码
while (counter.get() == maxSize){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
mq.add(object);
counter.getAndIncrement();
System.out.println("put:"+object+" size:"+counter.get());
lock.notify();
}
}
public Object offer(){
synchronized (lock){
//if (this.counter.get() <= minSize){ 错误代码
while (counter.get() == minSize){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Object object = mq.remove(0);
counter.getAndDecrement();
System.out.println("offer:" + object + " size:" + counter.get()+" "+Thread.currentThread().getName());
lock.notify();
return object;
}
}
}
上面是 模拟的阻塞队列
package com.testredis;
import java.util.Random;
/**
* Created by Administrator on 2017/3/2.
*/
public class PutThread implements Runnable{
private TestBlockingQueue mq = null;
private MyQueue myQueue = null;
public PutThread(TestBlockingQueue mq){
this.mq = mq;
}
public PutThread(MyQueue myQueue){
this.myQueue = myQueue;
}
@Override
public void run() {
Random r = new Random(1000);
r.nextInt();
mq.put(r.nextInt()+"");
//myQueue.put(r.nextInt()+"");
}
}
这个是 存储线程
package com.testredis;
/**
* Created by Administrator on 2017/3/2.
*/
public class GetThread implements Runnable {
private TestBlockingQueue mq ;
private MyQueue myQueue;
public GetThread(TestBlockingQueue mq){
this.mq = mq;
}
public GetThread(MyQueue myQueue){
this.myQueue = myQueue;
}
@Override
public void run() {
mq.offer();
//myQueue.take();
}
}
这个是 获取线程
package com.testredis.single;
import com.testredis.GetThread;
import com.testredis.MyQueue;
import com.testredis.PutThread;
import com.testredis.TestBlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Created by Administrator on 2017/3/2.
*/
public class Main {
Object lock = new Object();
AtomicInteger count = new AtomicInteger(1);
public static void main(String[] args) {
ArrayBlockingQueue getArrayQueue = new ArrayBlockingQueue(100);
ArrayBlockingQueue putArrayQueue = new ArrayBlockingQueue(100);
ExecutorService getPool = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, getArrayQueue);
ExecutorService putPool = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, putArrayQueue);
TestBlockingQueue mq = new TestBlockingQueue(2, 5);
//MyQueue mq = new MyQueue(2,5);
for (int i = 0; i < 100; i++) {
PutThread put = new PutThread(mq);
putPool.execute(put);
}
for (int i = 0; i < 100; i++) {
GetThread get = new GetThread(mq);
getPool.execute(get);
}
putPool.shutdown();
getPool.shutdown();
}
}
定义了两个线程池进行测试 。
如果采用标记错误代码的方式(if)去实现的时候,线程进行判断然后 调用wait方法(释放锁并且线程会在进行等待,注意:这里已经跨过判断,如果线程唤醒将直接进行下面的操作 )。这个问题 就很明白说明wait方法是施放锁的。