欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java多线程之wait,notify例子思考

程序员文章站 2022-07-12 19:33:48
...

       今天来写一篇Java关于多线程之线程通信例子。这是我学Java和工作这些年来,首次发表的博文,自己支持自己一下。

题目要求:写一个Java多线程程序,要求子线程循环输出10次,然后主线程循环输出10次,再接着子循环输出10次,再然后主线程循环输出10次。。。如此往复10次。

请大家帮我分析下,我的代码例子如下:

package org.jabari.tech.test;
public class ConcurrentTest1 {   
    class BizObj {
        //当前执行游标是否在子线程(true:子线程执行;false:父线程执行)
        private boolean cursorInSub;       
        public BizObj(boolean cursorInSub) {
            super();
            this.cursorInSub = cursorInSub;
        }
        public boolean isCursorInSub() {
            return cursorInSub;
        }
        public void setCursorInSub(boolean cursorInSub) {
            this.cursorInSub = cursorInSub;
        }       
    }
    
    
    public static void main(String[] args){
        ConcurrentTest1 t = new ConcurrentTest1();
        //创建一个锁对象,默认当前执行子线程。
        final BizObj objLock = t.new BizObj(true);
        new Thread(new Runnable(){
            public void run() {
                for(int j=0;j<10;j++){
                    synchronized(objLock) {
                        while (!objLock.isCursorInSub()) {
                            try {
                                objLock.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        for (int i = 0; i < 10; i++) {
                            System.out.println(Thread.currentThread().getName()+"-loop["+j+"]-"+i);
                        }
                        objLock.setCursorInSub(false);
                        objLock.notify();
                    }
                }
                
            }
            
        },"sub").start();
        //这里其实不需要再New一个主线程执行,因为main方法本身就是一个主线程单独执行。
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
                for(int j=0;j<10;j++){
                        synchronized(objLock) {
                            while (objLock.isCursorInSub()) {
                                try {
                                    objLock.wait();
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            for (int i = 0; i < 10; i++) {
                                System.out.println(Thread.currentThread().getName()+"-loop["+j+"]-"+i);
                            }
                            objLock.setCursorInSub(true);
                            objLock.notify();
                        }
                    
                }
//            }
//        },"main").start();       
//        System.out.println(Thread.currentThread().getName()+" Finishes!");
    }
}
 
看了不少大牛的视频讲解,JDK说明,和Thinking In Java 4th 中关于wait,notify/notifyAll的说明,
分析领悟如下:
1.    wait,notify/notifyAll是针对获得某对象同步锁的对象而言,不是对线程而言的。wait,notify/notifyAll,是所有对象都有的方法,当然线程对象也有这些方法,任何对象都有同步锁。
2.   这段代码synchronized(b) {....while(cond) { 
b.wait();
......  }的意思是什么?
   答:这是一段同步代码块,b是同步锁资源对象。“同步”表示在同一个时刻,只允许一个线程能访问b的synchronized方法.当前线程满足了cond,执行b.wait()后,当前线程便被阻塞进入了b对象的等待队列中(Waiting Queue)中,暂时释放对象b的同步锁,给其他线程获取b的同步锁的机会。线程的sleep,interrupt方法同样也会使当前线程阻塞,但他们不会释放对象锁。之所以用while()循环,是防止假唤醒现象,保证可靠性。
3.   当你不在正确的对象上使用synchronized,wait,notity,会造成java.lang.IllegalMonitorStateException,使用时,必须要是对同一个对象,执行这3个方法。