并发编程的历史综述与最新进展以及在HotSpot中的具体实现
ZHH2009
2014-08-04
群里有关多线程并发同步的贴子也有一些,但是还是缺乏系统性,也缺乏深度,
开这个贴,希望集中讨论有关多线程的主题,把所有细节讨论清楚。 此贴记录与并发编程相关的历史综述与最新进展以及在HotSpot中的具体实现。 目前我在HotSpot中研究并发和GC两大模块,会不定期更新此贴的内容。 |
|
ZHH2009
2014-08-04
下面这些书对于这个主题有一些帮助:
入门类: ------------ 【Java核心技术(卷I)】 http://book.douban.com/subject/3146174/ 第14章 多线程 【Java线程】 http://book.douban.com/subject/1768767/ 进阶类: ------------ 【深入理解Java虚拟机 : JVM高级特性与最佳实践】 http://book.douban.com/subject/24722612/ 第12、13章 【java并发编程实战】 http://book.douban.com/subject/10484692/ 【多处理器编程的艺术】 http://book.douban.com/subject/24700553/ 【Windows并发编程指南】 http://book.douban.com/subject/4214617/ 后续补充…… |
|
ZHH2009
2014-08-04
HotSpot中与这个主题相关的实现代码
(这里基于OpenJDK 8的代码 http://hg.openjdk.java.net/jdk8/jdk8/tags): 多数代码都归到runtime模块(hotspot\src\share\vm\runtime), ----------------------------------------------- basicLock biasedLocking monitorChunk mutex mutexLocker objectMonitor os osThread park synchronizer thread vmThread ----------------------------------------------- 归到interpreter模块(hotspot\src\share\vm\interpreter)的有: ----------------------------------------------- interpreterRuntime中的monitorenter和monitorexit TemplateTable::monitorenter TemplateTable::monitorexit TemplateTable::_return AbstractInterpreterGenerator::generate_method_entry(zerolocals_synchronized) ----------------------------------------------- 归到classfile模块(hotspot\src\share\vm\classfile)的有: ----------------------------------------------- javaClasses中的java_lang_Thread和java_lang_ThreadGroup类 ----------------------------------------------- 归到oops模块(hotspot\src\share\vm\oops)的有: ----------------------------------------------- markOop ----------------------------------------------- 归到prims模块(hotspot\src\share\vm\prims)的有: ----------------------------------------------- jvm unsafe JDK层的相关代码: java code --------------------- jdk\src\share\classes\java\lang\Object.java jdk\src\share\classes\java\lang\Runnable.java jdk\src\share\classes\java\lang\Thread.java jdk\src\share\classes\java\lang\ThreadDeath.java jdk\src\share\classes\java\lang\ThreadGroup.java jdk\src\share\classes\java\lang\ThreadLocal.java native code --------------------- jdk\src\share\native\java\lang\Object.c jdk\src\share\native\java\lang\Thread.c |
|
ZHH2009
2014-08-04
这楼说明java.lang.Thread如何对应到jvm、os层的线程,
以及java线程初始化和启动过程 对于下面的代码: public class ThreadTest { public static void main(String[] args) { Thread t = new Thread(); t.start(); } } 在Thread t = new Thread()这一步还没有在HotSpot中创建或启动相关的线程, 而是在t.start()这一步才开始。 Thread.start的代码 public synchronized void start() { //...... boolean started = false; try { start0(); started = true; } finally { //...... } 其中的start0是一个native方法,除了start0外,还有stop0、suspend0等等, 这些native方法通过jdk\src\share\native\java\lang\Thread.c关联到hotspot\src\share\vm\prims\jvm.cpp //jdk\src\share\native\java\lang\Thread.c static JNINativeMethod methods[] = { {"start0", "()V", (void *)&JVM_StartThread}, {"stop0", "(" OBJ ")V", (void *)&JVM_StopThread}, {"isAlive", "()Z", (void *)&JVM_IsThreadAlive}, {"suspend0", "()V", (void *)&JVM_SuspendThread}, {"resume0", "()V", (void *)&JVM_ResumeThread}, {"setPriority0", "(I)V", (void *)&JVM_SetThreadPriority}, {"yield", "()V", (void *)&JVM_Yield}, {"sleep", "(J)V", (void *)&JVM_Sleep}, {"currentThread", "()" THD, (void *)&JVM_CurrentThread}, {"countStackFrames", "()I", (void *)&JVM_CountStackFrames}, {"interrupt0", "()V", (void *)&JVM_Interrupt}, {"isInterrupted", "(Z)Z", (void *)&JVM_IsInterrupted}, {"holdsLock", "(" OBJ ")Z", (void *)&JVM_HoldsLock}, {"getThreads", "()[" THD, (void *)&JVM_GetAllThreads}, {"dumpThreads", "([" THD ")[[" STE, (void *)&JVM_DumpThreads}, {"setNativeName", "(" STR ")V", (void *)&JVM_SetNativeThreadName}, }; //这里的jclass cls对应java.lang.Thread //TODO HotSpot内部如何解析native方法? JNIEXPORT void JNICALL Java_java_lang_Thread_registerNatives(JNIEnv *env, jclass cls) { (*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(methods)); } 上面以JVM开头的方法都在hotspot\src\share\vm\prims\jvm.cpp中, 例如java.lang.Thread类的start0方法对应JVM_StartThread方法: JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread)) JVMWrapper("JVM_StartThread"); JavaThread *native_thread = NULL; // We cannot hold the Threads_lock when we throw an exception, // due to rank ordering issues. Example: we might need to grab the // Heap_lock while we construct the exception. bool throw_illegal_thread_state = false; //...... JVM_END 如果想跟踪线程的创建和启动过程,就可以在JVM_StartThread打断点来跟踪调试。 后续补充...... 理清java.lang.Thread和HotSpot中的JavaThread、OSThread之间的关系, 每个java.lang.Thread都由一个JavaThread对象表示, 对于OSThread要分不同os来描述, 在Windows里,每个OSThread都代表了一个Windows线程(通过_beginthreadex来创建)。 |
|
ZHH2009
2014-08-04
synchronized方法和synchronized块在字节码级的简单介绍
|
|
ZHH2009
2014-08-04
Object.wait/notify的一些疑惑
当线程A执行Object.wait后, 另一线程B执行完notify,并不会马上触发通知事件, 而是在退出同步块或同步方法执行到InterpreterRuntime::monitorexit时, 这就解释了Object.notify()的java doc中那句话:The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object 同步块由monitorexit字节码对应的汇编代码触发InterpreterRuntime::monitorexit, 同步方法通常对应一条return或Xreturn字节码,它们对应的汇编代码也会触发InterpreterRuntime::monitorexit。 对于上面存在一种例外, HotSpot VM提供了一个SyncKnobs配置参数,可以在执行notify时提前发出通知事件, 像这样配置: SyncKnobs="MoveNotifyee=5" |
|
ZHH2009
2014-08-04
HotSpot VM中在实现Object.notify时是如何选择要唤醒的线程的?
如果有多个线程在等待,要唤醒哪个线程其实是看哪个线程先执行wait的, 每次Object.notify只选择第一个执行wait的那个线程。 具体代码在ObjectMonitor::AddWaiter/DequeueWaiter/DequeueSpecificWaiter |
|
ZHH2009
2014-08-04
占楼......
|
|
ZHH2009
2014-08-04
占楼......
|
|
ZHH2009
2014-08-04
占楼......
|