`
k_lb
  • 浏览: 856198 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论
  • kitleer: 据我所知,国内有款ETL调度监控工具TaskCTL,支持ket ...
    kettle调度

Java Thread in JVM

 
阅读更多

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" /><shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 13.5pt; HEIGHT: 9.75pt" alt="" type="#_x0000_t75"><imagedata o:href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/chars/arrwdbrt.gif" src="file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image001.gif"></imagedata></shape>...

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. :-)

分享到:
评论

相关推荐

    实战Java虚拟机——JVM故障诊断与性能优化

    5. **异常诊断**:书中会介绍如何通过日志、堆转储(Heap Dump)、线程转储(Thread Dump)等手段来诊断常见的JVM问题,如OutOfMemoryError、StackOverflowError等。 6. **JVM参数设置**:熟练掌握JVM启动参数的...

    Java并发编程实践(java concurrency in practice)pdf (java多线程总结.ppt)

    Java提供了`Thread`类和`Runnable`接口来实现线程,同时讲解了`start()`与`run()`方法的区别。 2. **并发模型**:Java并发模型基于共享内存,其中线程通过内存共享进行通信。书中会讲解监视器(Monitor)、锁(Lock...

    出现Exception in threadmain java.lang.NoClassDefFoundError的各种可能情况.doc

    在Java编程中,遇到“Exception in thread 'main' java.lang.NoClassDefFoundError”是一种常见的异常情况,这通常意味着JVM在运行时未能找到指定的类定义。此错误不同于ClassNotFoundException,后者发生在尝试加载...

    JVM线程状态和Thread.sleep的实现原理探究.pdf

    在探究JVM线程状态以及Thread.sleep的实现原理时,我们首先需要了解Java线程与操作系统线程之间的关系。在Java虚拟机(JVM)中,每个线程通常都是以一对一的关系映射到操作系统线程上的。然而,尽管两者在实现上是...

    JAVA JVM性能调优监控工具详解

    ### JAVA JVM性能调优监控工具详解 在Java开发过程中,特别是在企业级应用中,经常会遇到各种性能瓶颈问题,如内存溢出(`OutOfMemoryError`)、内存泄露、线程死锁、锁争用等问题。这些问题如果不能及时有效地解决...

    面试-Java一些常见面试题+题解之JVM-JVM.zip

    9. **线程并发**:Java提供了多线程编程,包括Thread类和Runnable接口。线程池(ExecutorService)可以有效管理线程,避免过度创建销毁带来的开销。 10. **异常处理**:Java异常分为检查异常和运行时异常,通过try-...

    java故障排查ThreadDump

    - JVM参数设置:通过在启动Java应用时添加`-XX:+HeapDumpOnOutOfMemoryError`参数,当出现内存溢出时,JVM会自动生成包括Thread Dump在内的Heap Dump文件。 2. **理解Thread状态** - **NEW**:新创建但尚未启动的...

    java thread 分析

    Java线程Dump,也称为线程快照,是JVM在特定时刻捕获的所有活动线程的状态和堆栈跟踪的记录。它包含了每个线程的ID、名称、状态、优先级、持有或等待的锁信息以及调用堆栈。线程Dump对于识别死锁、线程阻塞、资源争...

    thinking in java 文档

    10. **Java虚拟机(JVM)**:理解JVM的工作原理,包括类加载、内存模型、垃圾回收等,对优化Java程序性能至关重要。 11. **Java标准库**:Java标准库(Java API)包含了大量预先定义的类和接口,如IO、网络编程、...

    Thinking in java 中文版

    9. **Java虚拟机(JVM)**:了解JVM的工作原理,包括类加载、内存管理和垃圾回收,对于优化程序性能和排查问题至关重要。 10. **Java标准库(JDK)**:熟练使用Java提供的各种API,如Math、String、Date、...

    java 内存dump分析和thread dump(java core)分析

    接下来,Thread Dump(Java Core)是JVM在某个时间点捕获的当前所有线程的状态快照,包括线程ID、线程状态、堆栈跟踪等信息。分析Thread Dump有助于发现线程阻塞、死锁等问题。常见的Thread Dump分析工具有: 1. **...

    java编程思想thinking in java

    13. **Java虚拟机(JVM)**:JVM是Java程序运行的基础,它负责解析字节码,执行指令,并管理内存。 以上只是《Java编程思想》中部分核心知识点的概述,实际书籍中涉及的内容更为丰富,包括网络编程、数据库连接、...

    最新Thinking in java第四版经典版

    综上所述,《最新Thinking in Java第四版经典版》通过全面而深入的讲解,不仅覆盖了Java编程语言的基础,还包括其核心概念、面向对象编程、高级特性、并发编程、I/O、网络编程以及JVM等,帮助读者建立对Java语言全...

    Java Concurrency In Practice.pdf

    书中介绍了几种机制,如`Runtime.addShutdownHook(Thread)`方法,用于处理JVM关闭前的清理工作。 #### 八、应用线程池 ##### 8.1 任务与执行策略之间的隐式耦合 任务与执行策略之间的隐式耦合可能会导致不可预测的...

    Thinking in Java 习题答案

    6. **多线程**:Java提供了丰富的API来支持并发编程,如Thread类、synchronized关键字、volatile变量、Lock接口等。习题会涵盖同步控制、线程通信等复杂问题。 7. **输入/输出(I/O)**:Java的I/O系统包括文件操作、...

    Thinking in java java源代码

    5. **多线程**:Java内置了对多线程的支持,通过实现Runnable接口或继承Thread类可以创建线程。线程同步机制,如synchronized关键字、wait()、notify()和notifyAll()方法,用于避免并发访问共享资源时产生的竞态条件...

    thinking in java 源码

    7. **多线程**:Java内置了对多线程的支持,源码中会有Thread和Runnable接口的使用,以及同步机制如synchronized关键字和java.util.concurrent包的高级工具。 8. **输入/输出(I/O)系统**:Java I/O库提供了处理...

    java.lang.UnsupportedClassVersionError Bad version number in .class file异常的解决办法

    这种错误通常发生在编译器版本与实际使用的JVM版本不匹配的情况下,比如使用了较新的Java编译器生成的`.class`文件在较旧的JVM上运行时就会触发此类异常。 #### 二、错误原因分析 该错误的主要原因是由于MyEclipse...

    Java程序设计基础

    8. 多线程:Java内置多线程支持,提供Thread类进行线程管理。 9. 动态性:Java允许程序库随时间发展而扩展,不影响已有程序。 Java开发人员在全球范围内分布广泛,尤其在北美地区,而Java开发者的需求也在持续增长...

Global site tag (gtag.js) - Google Analytics