java多线程wait_1.Java多线程之wait和notify

本文通过一个简单的Java程序,深入解析wait和notify方法在多线程中的应用,如何实现两个线程交替打印'ab'。程序中,两个线程共享一个对象锁,通过wait和notify进行线程间的通信和同步,确保打印顺序。理解这两个方法的关键在于它们如何唤醒和释放对象锁。
摘要由CSDN通过智能技术生成

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

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

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

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

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

我们来看代码吧,

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

1 packagecn.javaBase.study_thread1;2

3

4 class MyRunnable implementsRunnable{5 privateString name;6 privateObject obj;7

8 publicMyRunnable(String n, Object o) {9 this.name =n;10 this.obj =o;11 }12

13 @Override14 public voidrun() {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 classThread5AB {34

35 public static void main(String[] args) throwsInterruptedException {36 //这个程序中 共同的锁对象

37 Object o = newObject();38

39 MyRunnable r1 = new MyRunnable("a", o);40 MyRunnable r2 = new MyRunnable("b", o);41

42 Thread th1 = newThread(r1);43 Thread th2 = newThread(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线程第一次切换执行的过程,后面就依次这样循环执行,

359da07a69b79981b01c97ad285c79c7.png

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值