• 1.Java多线程之wait和notify


    1.首先我们来从概念上理解一下这两个方法:

    (1)obj.wait(),当obj对象调用wait方法时,这个方法会让当前执行了这条语句的线程处于等待状态(或者说阻塞状态),并释放调用wait方法的对象的对象锁。

    当线程执行了obj.wait()这个语句之后,这个线程处于等待状态,需要其它线程用同一个obj对象调用notify或notifyAll方法,才可能唤醒这个处于等待状态的的线程。

    (2)obj.notify(), 调用这个方法,就是唤醒其它 在obj这对象锁上处于等待状态 的线程,被唤醒的线程 在得到对象锁后 就会继续执行。

    概念上的文字晦涩、让人理解的不够清晰,

    我们来看代码吧,

    这个小程序的目的就是:启两个线程,并让这两个线程切换着执行,并按序打印ababababababababababab。

     1 package cn.javaBase.study_thread1;
     2 
     3 
     4 class MyRunnable implements Runnable{
     5     private String name;
     6     private Object obj;
     7     
     8     public MyRunnable(String n, Object o) {
     9         this.name = n;
    10         this.obj = o;
    11     }
    12     
    13     @Override
    14     public void run() {
    15         synchronized (obj) {
    16             while (true) {
    17                 System.out.println(name);
    18                 obj.notify();  //当a线程执行到这里时,它就会唤醒另一个在obj对象锁中 处于等待状态的线程
    19                                 //(也就是另一个在obj对象锁中调用了obj.wait() 语句的线程)
    20                                 //注意,这里它不是唤醒 所有等待线程 中的任意一个, 而是唤醒 在obj这个对象锁上处于等待状态的 线程
    21                 try {
    22                     obj.wait();  //当a线程执行到这里,它就会让 当前线程a处于等待状态,并释放obj这个对象。
    23                     System.out.println("当前线程,会阻塞在这里");
    24                 } catch (InterruptedException e) {
    25                     e.printStackTrace();
    26                 }
    27             }
    28         }
    29     }
    30     
    31 }
    32 
    33 public class Thread5AB {
    34 
    35     public static void main(String[] args) throws InterruptedException {
    36         //这个程序中 共同的锁对象
    37         Object o = new Object();
    38         
    39         MyRunnable r1 = new MyRunnable("a", o);
    40         MyRunnable r2 = new MyRunnable("b", o);
    41         
    42         Thread th1 = new Thread(r1);
    43         Thread th2 = new Thread(r2);
    44         
    45         th1.start();
    46         Thread.sleep(500); //这个是保证打印a的线程先启动
    47         th2.start();
    48         
    49     }
    50 }

    为了描述方便, 假设 上面的th1 和th2 分别代表着a、b线程

    对于这个程序,重点应该是理解39、40行,r1和r2构造时,会什么传递的是同一个Object 类型的o对象,

    因为:当a线程执行到22行时,a线程就处于等待状态,这时候b线程执行,当b线程直线到18行时,b线程就可以唤醒阻塞在o对象锁上的线程,而此时a线程不就是那个阻塞在o对象锁上的线程吗,

    所以等b线程执行到18行时,a线程就被唤醒(但是这个时候a线程还不能进入synchronized代码块,就是这个对象锁中,因为进入这个代码块,需要有obj这个对象,obj这个对象就像是进入这个代码块的钥匙),

    接下来等到b线程执行到22行时,b线程就把obj这个对象释放了,自己进入等待状态,此时a线程已经处于唤醒了的状态,并可以得到obj这个对象,所以接下来a线程就可以继续执行synchronized代码块中的内容,

    这就是a、b线程第一次切换执行的过程,后面就依次这样循环执行,

    控制台就打印了我们想要的结果ababababab...

    重要的问题是,你要知道obj.notify()执行时,唤醒的是那个处于等待的线程,它唤醒的是在obj这个对象锁上处于等待的线程

    不知道这样解释的是否还可以,本人也是最近稿明白,

  • 相关阅读:
    搞IT的不如去养鸡养猪了
    matlabemacs运行matlab程序出错.不能调用matlab命令行模式
    微软利用全球天文望远镜数据建立宇宙地图
    程序人生2005年(30)
    IT领袖峰会精彩观点:4G时代不存在信令问题
    初识MySql数据库
    Android屏幕尺寸适配注意事项
    Java多线程详解(一)
    ios键盘高度
    ASP.NET MVC——Action的执行
  • 原文地址:https://www.cnblogs.com/WNof11020520/p/8780875.html
Copyright © 2020-2023  润新知