wait方法施放锁,notify方法持有锁

来源:互联网 发布:莱特币闪电网络 编辑:程序博客网 时间:2024/05/18 02:08

   先来看下例子,这个例子中明显能看出问题代码如下:


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方法是施放锁的。

0 0
原创粉丝点击