十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶(hù) + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專(zhuān)業(yè)推廣+無(wú)憂(yōu)售后,網(wǎng)站問(wèn)題一站解決
(wang hailong)
本文從JVM的角度探討Java Thread的語(yǔ)法和編譯結(jié)果。如果需要獲得第一手資料,請(qǐng)直接訪(fǎng)問(wèn)以下的資源——Java語(yǔ)言規(guī)范,Java虛擬機(jī)規(guī)范中有關(guān)線(xiàn)程的定義說(shuō)明。
本文旨在介紹這些比較重要的線(xiàn)程相關(guān)的規(guī)范,基本上不另作發(fā)揮。(除了提到微軟的“公共語(yǔ)言基礎(chǔ)構(gòu)造”。:-)
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
網(wǎng)頁(yè)設(shè)計(jì)是網(wǎng)站建設(shè)的前奏,好的網(wǎng)頁(yè)設(shè)計(jì)更深度的剖析產(chǎn)品和設(shè)計(jì)風(fēng)格定位,結(jié)合最新的網(wǎng)頁(yè)設(shè)計(jì)流行趨勢(shì),與WVI應(yīng)用標(biāo)準(zhǔn),設(shè)計(jì)出具企業(yè)表現(xiàn)力,大器而深穩(wěn)的網(wǎng)站界面設(shè)。成都創(chuàng)新互聯(lián)成立于2013年,是成都網(wǎng)站建設(shè)公司:提供企業(yè)網(wǎng)站設(shè)計(jì),品牌網(wǎng)站設(shè)計(jì),營(yíng)銷(xiāo)型企業(yè)網(wǎng)站建設(shè)方案,響應(yīng)式網(wǎng)站設(shè)計(jì),微信平臺(tái)小程序開(kāi)發(fā),專(zhuān)業(yè)建站公司做網(wǎng)站。
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 :-)
.NET/ecma/">http://msdn.microsoft.com/net/ecma/
詳見(jiàn)http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#30531。
用synchronized關(guān)鍵字修飾的方法,分為兩種情況:(static)靜態(tài)方法,和實(shí)例方法。
(static)靜態(tài)方法的“鎖”是這個(gè)擁有這個(gè)方法的對(duì)象的Class對(duì)象;實(shí)例方法的“鎖”是this,擁有這個(gè)方法的當(dāng)前對(duì)象實(shí)例。
怎么理解這段話(huà),看一看下面的例子就明白了。
下面兩段代碼的效果完全相同。代碼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) {
...
}
}
}
這一節(jié),我們來(lái)看一看synchronized關(guān)鍵字編譯之后的java虛擬機(jī)指令是什么。
如果需要第一手資料,請(qǐng)參見(jiàn)java虛擬機(jī)規(guī)范相關(guān)的部分
http://java.sun.com/docs/books/vmspec/2nd-edition/html/Compiling.doc.html#6530
這段規(guī)范里面講到,java虛擬機(jī)規(guī)范提供兩條指令,monitorenter和monitorexit,來(lái)支持線(xiàn)程。但是對(duì)于上一節(jié)講到的,用synchronized修飾的方法來(lái)說(shuō),并不使用這兩個(gè)方法,而只是簡(jiǎn)單地用ACC_SYNCHRONIZED標(biāo)志修飾。虛擬機(jī)調(diào)用方法的時(shí)候會(huì)檢查這個(gè)標(biāo)志,進(jìn)行同步。
synchronized語(yǔ)句的編譯結(jié)果對(duì)應(yīng)monitorenter和monitorexit兩條指令。
比如,下面的代碼:
void onlyMe(Foo f) {
synchronized(f) {
doSomething();
}
}
的編譯結(jié)果是
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
詳見(jiàn)http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc9.html
monitorenter定義的一段節(jié)錄:
Operation : Enter monitor for object
Operand Stack : ..., objectref
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.
這段話(huà)的意思是說(shuō),monitorenter操作的目標(biāo)一定要是一個(gè)對(duì)象,類(lèi)型是reference。Reference實(shí)際就是堆里的一個(gè)存放對(duì)象的地址。每個(gè)對(duì)象(reference)都有一個(gè)monitor對(duì)應(yīng),如果有其它的線(xiàn)程獲取了這個(gè)對(duì)象的monitor,當(dāng)前的線(xiàn)程就要一直等待,直到獲得monitor的線(xiàn)程放棄monitor,當(dāng)前的線(xiàn)程才有機(jī)會(huì)獲得monitor。
如果monitor沒(méi)有被任何線(xiàn)程獲取,那么當(dāng)前線(xiàn)程獲取這個(gè)monitor,把monitor的entry count設(shè)置為1。表示這個(gè)monitor被1個(gè)線(xiàn)程占用了。
當(dāng)前線(xiàn)程獲取了monitor之后,會(huì)增加這個(gè)monitor的時(shí)間計(jì)數(shù),來(lái)記錄當(dāng)前線(xiàn)程占用了monitor多長(zhǎng)時(shí)間。
我們看到,monitor這個(gè)詞在java虛擬機(jī)規(guī)范規(guī)定出現(xiàn),但是在java語(yǔ)言和api文檔里面并沒(méi)有出現(xiàn)。monitor是藏在線(xiàn)程同步后面的原理和概念。
詳見(jiàn)http://java.sun.com/docs/books/vmspec/2nd-edition/html/Threads.doc.html。
這段規(guī)范詳細(xì)地介紹了thread和lock的原理。下面給出這段規(guī)范的highlight。
8.4 Nonatomic Treatment of double
and long
Variables (double和long類(lèi)型的非原子操作。)
8.7 Rules for volatile
Variables
8.10 Example: Possible Swap
8.11 Example: Out-of-Order Writes
如果對(duì)列出的這些highlight感興趣,請(qǐng)?jiān)L問(wèn)相應(yīng)的java虛擬機(jī)規(guī)范網(wǎng)址。
本文主要討論java相關(guān)規(guī)范的內(nèi)容。規(guī)范文檔非常重要,尤其對(duì)于java,C#這種生成中間代碼的語(yǔ)言來(lái)說(shuō)。
上面說(shuō)的是java的相關(guān)規(guī)范。這里順便提一下微軟.Net的相關(guān)規(guī)范。
微軟的“公共語(yǔ)言基礎(chǔ)構(gòu)造”規(guī)范:
Microsoft CLI -- Common Language Infrastructure (sorry, off the topic :-)
http://msdn.microsoft.com/net/ecma/
這個(gè)網(wǎng)址上有C#語(yǔ)言規(guī)范,CLI規(guī)范的下載。
Enjoy it. :-)