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就出自于这个字节码的定义: