Java精通并发-wait与sleep方法字节码分析

在上一次https://www.cnblogs.com/webor2006/p/11372521.html中对于Thread类和Runnable接口有了一个基本的认识,这次咱们继续巩固基础,首先先新建一个全新的工程,专门用来学习Java并发相关的:

好,下面先来对Object中的wait()和Thread.sleep()方法进行官方说明解读:

wait():

打开Object类可以发现wait()方法有几个重载形式的:

其中我们平常常用的一般都是无参的,如:

其中又调用了一个带参数的,发现也是native的:

所以可以发现跟线程相关的其实都是跟操作系统底层相关的,下面来重点读一下不带参数的javadoc,里面的说明非常之重要:

以上就是关于此方法的全部解读,从中也能看到有好多重要的知识点,下面先来试一下wait():

就是文档中的这点说明:

所以可以修改一下:

sleep():

它是位于Thread中的,先来看一下它的说明:

所以,跟wait()的区别就已经非常之明显了,下面总结一下。

总结:

在调用wait()方法时,线程必须要持有被调用对象的锁,当调用wait()方法之后,线程就会释放掉该对象的锁(monitor)。

在调用Thread类的sleep()方法时,线程是不会释放掉对象的锁的。

锁在字节码的表现:

其实关于锁在字节码的表现在JVM的学习中已经学习过了,不过这里再来回忆一下,将其反编译一下:

xiongweideMacBook-Pro:main xiongwei$ javap -c com/javacurrency/test1/MyTest1.class
Compiled from "MyTest1.java"
public class com.javacurrency.test1.MyTest1 {
  public com.javacurrency.test1.MyTest1();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]) throws java.lang.InterruptedException;
    Code:
       0: new           #2                  // class java/lang/Object
       3: dup
       4: invokespecial #1                  // Method java/lang/Object."<init>":()V
       7: astore_1
       8: aload_1
       9: dup
      10: astore_2
      11: monitorenter
      12: aload_1
      13: invokevirtual #3                  // Method java/lang/Object.wait:()V
      16: aload_2
      17: monitorexit
      18: goto          26
      21: astore_3
      22: aload_2
      23: monitorexit//为啥有两个,是为了保证不管异常最终都会保证能释放锁
      24: aload_3
      25: athrow
      26: return
    Exception table:
       from    to  target type
          12    18    21   any
          21    24    21   any
}

所示javadoc中的monitor就出自于这个字节码的定义:

posted on 2019-08-24 14:10  cexo  阅读(447)  评论(0编辑  收藏  举报

导航