Java线程wait/notify讲解

来源:互联网 发布:英语公众号推荐 知乎 编辑:程序博客网 时间:2024/05/17 22:53

wait:当前访问对象的线程被阻塞,并且放弃之前拥有的对象锁,直到被notify/notifyAll方法唤醒,在原来中断的地方继续执行

扩展:线程从原来中断的地方继续执行的原因:操作系统是统一管理所有的软硬件资源的软件,进程是程序分配资源的单位,线程则是进程进行资源进一步划分的最小的分配资源单位,当线程或进程被中断的时候,操作系统会自动将当前线程/进程的状态存入线程控制块(TCB)和进程控制块(PCB),然后阻塞当前运行的线程/进程,当线程/进程达到运行的条件,操作系统会从之前保存的TCB/PCB中读取信息,恢复中断前的状态,所以线程/进程就成从中断的地方继续运行

notify:唤醒访问目标对象的1个阻塞线程
注意:如果存在多个线程访问同一个对象,notify唤醒的线程是随机的,notifyAll可以唤醒所有的阻塞线程

测试案例:

package com.zhiwei.thread;public class WaitAndNotify {   static Object object=new Object();    public static void main(String[] args) throws InterruptedException{      threadWait tw = new threadWait();      threadNotify tn = new threadNotify();      Thread th1=new Thread(tw);      Thread th2=new Thread(tn);      th1.start();      th2.start();    }    static class threadWait implements Runnable{        @Override        public void run() {            synchronized (object) {                 try {                    System.out.println(Thread.currentThread().getName()+":object对象锁释放前!");                    object.wait();              System.out.println(Thread.currentThread().getName()+":object对象锁释放后!");                 } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }    static class threadNotify implements Runnable{        @Override        public void run() {            synchronized (object) {                try {                    System.out.println(Thread.currentThread().getName()+":object对象锁获取前!");                    object.notify();                     System.out.println(Thread.currentThread().getName()+":object对象锁获取后!(JVM决定唤醒另外线程)");                } catch (Exception e) {                    e.printStackTrace();                }            }               }    }}

结果:

Thread-0:object对象锁释放前!
Thread-1:object对象锁获取前!
Thread-1:object对象锁获取后!(JVM决定唤醒另外线程)
Thread-0:object对象锁释放后!

分析:

①:线程threadWait执行时synchronized (object)的原因,线程threadNotify线程阻塞,等待threadWait释放对象锁才可以执行
②:当threadWait执行到 object.notify(); 的时候,threadWait线程被手动阻塞中断,因此控制台只会输出“Thread-0:object对象锁释放前!”
③:因为threadWait释放对象锁,所以线程threadNotify运行,当执行object.notify(); 的时候,因为object只有一个阻塞线程,因此threadWait线程被唤醒,但是由于threadNotify还在执行同步代码块,因此线程threadWait进入阻塞状态,当线程threadNotify执行完成同步代码块,控制台输出”Thread-1:object对象锁获取前!
Thread-1:object对象锁获取后!(JVM决定唤醒另外线程)”
④:threadNotify持有的object对象锁释放,threadWait获取对象锁继续执行,控制台输出”Thread-0:object对象锁释放后!”

0 0