Java Thread in JVM

原创 2003年03月21日 09:21:00

Java Thread in JVM

(wang hailong)

本文从JVM的角度探讨Java Thread的语法和编译结果。如果需要获得第一手资料,请直接访问以下的资源——Java语言规范,Java虚拟机规范中有关线程的定义说明。

本文旨在介绍这些比较重要的线程相关的规范,基本上不另作发挥。(除了提到微软的“公共语言基础构造”。:-)

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

Java Language Specification

http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#30531

 

JVM Specification

http://java.sun.com/docs/books/vmspec/2nd-edition/html/Compiling.doc.html#6530

http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc9.html

http://java.sun.com/docs/books/vmspec/2nd-edition/html/Threads.doc.html

 

Microsoft CLI -- Common Language Infrastructure (sorry, off the topic :-)

http://msdn.microsoft.com/net/ecma/

1.synchronized method java语言规范

详见http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#30531

 

synchronized关键字修饰的方法,分为两种情况:(static)静态方法,和实例方法。

 (static)静态方法的“锁”是这个拥有这个方法的对象的Class对象;实例方法的“锁”是this,拥有这个方法的当前对象实例。

怎么理解这段话,看一看下面的例子就明白了。

下面两段代码的效果完全相同。代码1 ==代码2

代码1

class Test {

       int count;

       synchronized void bump() { count++; }

       static int classCount;

       static synchronized void classBump() {

              classCount++;

       }

}

代码2

class BumpTest {

       int count;

       void bump() {

              synchronized (this) {

                     count++;

              }

       }

       static int classCount;

       static void classBump() {

              try {

                     synchronized (Class.forName("BumpTest")) {

                            classCount++;

                     }

              } catch (ClassNotFoundException e) {

                            ...

              }

       }

}

 

2synchronized关键字的编译结果

这一节,我们来看一看synchronized关键字编译之后的java虚拟机指令是什么。

如果需要第一手资料,请参见java虚拟机规范相关的部分

http://java.sun.com/docs/books/vmspec/2nd-edition/html/Compiling.doc.html#6530

 

这段规范里面讲到,java虚拟机规范提供两条指令,monitorentermonitorexit,来支持线程。但是对于上一节讲到的,用synchronized修饰的方法来说,并不使用这两个方法,而只是简单地用ACC_SYNCHRONIZED标志修饰。虚拟机调用方法的时候会检查这个标志,进行同步。

synchronized语句的编译结果对应monitorentermonitorexit两条指令。

比如,下面的代码:

void onlyMe(Foo f) {

    synchronized(f) {

        doSomething();

    }

}

的编译结果是

Method void onlyMe(Foo)

   0      aload_1                        // Push f 

   1      astore_2                // Store it in local variable 2

   2      aload_2                        // Push local variable 2 (f)

   3      monitorenter               // Enter the monitor associated with f

   4      aload_0                        // Holding the monitor, pass this and...

   5      invokevirtual #5            // ...call Example.doSomething()V

   8       aload_2                        // Push local variable 2 (f)

   9       monitorexit                   // Exit the monitor associated with f

  10       return                           // Return normally

  11       aload_2                        // In case of any throw, end up here

  12      monitorexit                 // Be sure to exit monitor...

  13      athrow                         // ...then rethrow the value to the invoker

3monitorentermonitorexit

详见http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc9.html

 

monitorenter定义的一段节录:

Operation :  Enter monitor for object

Operand Stack :  ..., objectref <?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />...

Description :

The objectref must be of type reference.

Each object has a monitor associated with it. The thread that executes monitorenter gains ownership of the monitor associated with objectref. If another thread already owns the monitor associated with objectref, the current thread waits until the object is unlocked, then tries again to gain ownership. If the current thread already owns the monitor associated with objectref, it increments a counter in the monitor indicating the number of times this thread has entered the monitor. If the monitor associated with objectref is not owned by any thread, the current thread becomes the owner of the monitor, setting the entry count of this monitor to 1.

 

这段话的意思是说,monitorenter操作的目标一定要是一个对象,类型是referenceReference实际就是堆里的一个存放对象的地址。每个对象(reference)都有一个monitor对应,如果有其它的线程获取了这个对象的monitor,当前的线程就要一直等待,直到获得monitor的线程放弃monitor,当前的线程才有机会获得monitor

如果monitor没有被任何线程获取,那么当前线程获取这个monitor,把monitorentry count设置为1。表示这个monitor1个线程占用了。

当前线程获取了monitor之后,会增加这个monitor的时间计数,来记录当前线程占用了monitor多长时间。

 

我们看到,monitor这个词在java虚拟机规范规定出现,但是在java语言和API文档里面并没有出现。monitor是藏在线程同步后面的原理和概念。

4Threads and Locks

详见http://java.sun.com/docs/books/vmspec/2nd-edition/html/Threads.doc.html

这段规范详细地介绍了threadlock的原理。下面给出这段规范的highlight

8.4 Nonatomic Treatment of double and long Variables doublelong类型的非原子操作。)

8.7 Rules for volatile Variables

8.10 Example: Possible Swap

8.11 Example: Out-of-Order Writes

如果对列出的这些highlight感兴趣,请访问相应的java虚拟机规范网址。

5Why specification?

本文主要讨论java相关规范的内容。规范文档非常重要,尤其对于javaC#这种生成中间代码的语言来说。

上面说的是java的相关规范。这里顺便提一下微软.Net的相关规范。

微软的“公共语言基础构造”规范:

Microsoft CLI -- Common Language Infrastructure (sorry, off the topic :-)

http://msdn.microsoft.com/net/ecma/

这个网址上有C#语言规范,CLI规范的下载。

Enjoy it. :-)

 

聊聊JVM(五)从JVM角度理解线程

这篇说说如何从JVM的角度来理解线程,可以对Java的线程模型有一个更加深入的理解,对GC的一些细节也会理解地更加深刻。本文基于HotSpot的OpenJDK7实现。 我们知道JVM主要是用C++...
  • ITer_ZC
  • ITer_ZC
  • 2014年12月10日 11:01
  • 9542

Java Thread Pool

原文链接,请看原文。 Java通过Executors提供四种线程池,分别为: newCachedThreadPool: 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无...
  • fly1183989782
  • fly1183989782
  • 2015年03月20日 20:10
  • 704

Java Thread BLOCKED和WAITING两种状态的区别(英)

Thread.State in Java? BLOCKED vs WAITING What is Thread.State in Java? What's it used...
  • masfay
  • masfay
  • 2014年02月27日 16:48
  • 4561

JVM: How to analyze Thread Dump

转载地址:https://www.javacodegeeks.com/2012/03/jvm-how-to-analyze-thread-dump.html 中文翻译:http://www.osch...
  • u010764427
  • u010764427
  • 2016年06月18日 21:15
  • 465

Thread Dump分析

thread dump获取 1. 发送信号 * In Unix, use "kill -3 " where pid is the Process ID of the JVM.(kill 信号列表)...
  • wanyanxgf
  • wanyanxgf
  • 2011年11月07日 19:58
  • 16020

关于jvm 中vmthread的问题

最近一个同事性能测试,20个并发,压了3分钟,tps急剧下降,jvm开始不响应通过排查发现,此时old区已满,并且cpu 100%完全被vmthread占用如果此时停止施压,那么过几分钟,jvm会回复...
  • pwlazy
  • pwlazy
  • 2011年08月17日 20:45
  • 6813

jvm 有 Daemon,non-daemon 两种线程

看见这两个,表示如何结束线程了, 即终止一个应用。 1》 non-daemon线程结束----强制daemon干活线程结束,不管它执行到哪里。   2》non-daemon线程结束---non-dae...
  • monica12
  • monica12
  • 2017年06月16日 13:14
  • 383

System.gc与finalize以及Thread对象何时被回收

System.gc()建议JVM进行一次垃圾回收。垃圾对象在被回收之前,其finalize方法会被JVM自动调用,用于做一些清除工作。简单地说,调用了System.gc()之后,java在内存回收过程...
  • zhangzeyuaaa
  • zhangzeyuaaa
  • 2015年12月30日 13:22
  • 1417

JVM源码分析之一个Java进程究竟能创建多少线程

虽然这篇文章的标题打着JVM源码分析的旗号,不过本文不仅仅从JVM源码角度来分析,更多的来自于Linux Kernel的源码分析,今天要说的是JVM里比较常见的一个问题这个问题可能有几种表述•一个Ja...
  • oPerform
  • oPerform
  • 2017年05月22日 17:59
  • 659

Java Thread in JVM

google_ad_client = "pub-8800625213955058";/* 336x280, 创建于 07-11-21 */google_ad_slot = "0989131976";...
  • java169
  • java169
  • 2008年05月23日 23:58
  • 224
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java Thread in JVM
举报原因:
原因补充:

(最多只允许输入30个字)