一个notify()的实例分析

来源:互联网 发布:螺栓重量软件 编辑:程序博客网 时间:2024/05/17 21:43

在java多线程编程中,就要涉及到了对于资源的访问,当多个线程同时访问一个资源的时候就要涉及到一种访问策略。java提供了锁的机制,就是一个线程访问这个资源的时候可以先把这个资源锁住可以用synchronized(the object)来锁定the object,其他访问这个资源的线程就进入阻塞状态,直到当前的线程执行了这个对象的notify或者notifyall其他访问这个对象的阻塞状态的线程才有可能变成就绪状态。其中notify是唤醒一个线程,而notifyall是唤醒所有阻塞进程。

如下是一个这方面的实例

 

package concurrent;import java.util.concurrent.TimeUnit;/** * Wait、Notify、NotifyAll的区别 * @author yydcj * Email:yydcj@163.com * 网址:<a>http://yydcj.iteye.com</a> */public class WaitNotify {private static int reduceThreadCount =0;/** * @param args */public static void main(String[] args) {WaitNotify notify = new WaitNotify();Source source = notify.new Source("source");for (int i = 0; i < 10; i++)notify.new ReduceThread(source).start();//try {//TimeUnit.SECONDS.sleep(5);//} catch (InterruptedException e) {//e.printStackTrace();//}notify.new AddThread(source).start();}class ReduceThread extends Thread{private Source source;public ReduceThread(Source source){super("ReduceThread-" + reduceThreadCount++);this.source = source; }public void run(){for (int i = 0; i < 10; i++){try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}source.reduceCount();}}}class AddThread extends Thread{private Source source;public AddThread(Source source){super("AddThread");this.source = source; }public void run(){for (int i = 0; i < 1; i++){try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}source.addCount();}}}class Source{private int count = 0;public Source(String name){//this.name = name;}public synchronized void addCount() {System.out.println(Thread.currentThread().getName()+": count+1="+ ++count);notify();}public synchronized void reduceCount() {while (count <= 0) {try {System.out.println(Thread.currentThread().getName()+" wait()");wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+": count-1="+ --count);}}}

 //output:

ReduceThread-1 wait()
ReduceThread-5 wait()
ReduceThread-8 wait()
ReduceThread-6 wait()
ReduceThread-4 wait()
ReduceThread-2 wait()
ReduceThread-0 wait()
AddThread: count+1=1
ReduceThread-7: count-1=0
ReduceThread-9 wait()
ReduceThread-3 wait()
ReduceThread-1 wait()
ReduceThread-7 wait()

 

我这里是用notify()来唤醒其中一个ReduceThread线程的(此时notify的是ReduceThread-7),然后ReduceThread-7执行完消费任务后又进入了wait()、10个reduce线程虽然是顺序实例化的,但是他们并不是顺序拿到souce对象的。依次拿到souce对象的1586420 这7个线程,各个线程因为count 为0释放了这个对象给其他的线程。然后AddThread拿到了这个对象,将count变为1,notify了一个线程,这个线程就是1。虽然1被notify了,但是他并没有取得对象,对象被7获取了并将count设置为0,所以等于说1这个线程醒来之后发现count依然为0,所以又wait了一遍

一个线程被notify之后并不认为已经获取了对象,依然需要去和其他线程抢对象才能继续执行下去。