Java除錯教程--多執行緒除錯(轉)
Java除錯教程--多執行緒除錯(轉)[@more@]摘要
最有價值的除錯工具是以執行緒為中心的。大部分 Java 錯誤都與執行緒互動有關。多執行緒除錯讓開發人員可以檢視應用程式中執行的每個執行緒中的執行情況。
--------------------------------------------------------------------------------
By Wing, 出處:Laura Bennett
Java除錯教程(六)--多執行緒除錯
SUN Laura Bennett
多執行緒除錯基礎
最有價值的除錯工具是以執行緒為中心的。大部分 Java 錯誤都與執行緒互動有關。多執行緒除錯讓開發人員可以檢視應用程式中執行的每個執行緒中的執行情況。
由於執行順序的易變性,查詢多執行緒應用程式中的錯誤比非執行緒化情況要困難得多。如果可以按相同的可預料順序執行指令,那麼除錯這些應用程式就可以變得非常簡單。當然,這將違背多執行緒化的目標。結果,許多 IDE 偵錯程式在這種情況下都不能起什麼作用,因為單步除錯程式碼會減緩除錯過程,並禁止重新建立錯誤事件。
多執行緒錯誤的型別
這裡有幾種常見的多執行緒編碼問題需要密切關注:
訪問違規。當兩個或更多執行緒試圖訪問同一個記憶體位置時,會發生這種問題。
死鎖。譬如說 Thread1 鎖定了 ResourceA,而 Thread2 鎖定了 ResourceB。然後Thread1試圖鎖定 ResourceB,並等待 ResourceB 變成可用的。同時,Thread2試圖鎖定 ResourceA 並等待 ResourceA 變成可用的。 結果:死鎖。防止死鎖的一種方法是不要讓程式在設定了鎖定時睡眠。還可以使用 synchronization() 來確保關鍵部分的程式碼一次只能由一個執行緒訪問。
資料爭用錯誤。資料爭用條件會鎖定應用程式,這種情況會時常發生,譬如雙擊滑鼠左鍵。在資料爭用的情況下資料通常會遭到破壞。要防止這種錯誤,應使變數不能被多個執行緒訪問。現在已經有工具可以分析這種問題並標誌可能發生資料爭用錯誤的變數。
同步錯誤。進行無用資訊收集時可能會發生這種問題。Java 會自動處理無用資訊收集。此時,所有執行緒都會從執行狀態變成暫掛。
使用 synchronized() 方法
不同版本的 JVM 實現執行緒優先順序的方法也可能不同,這會影響執行緒同步。我們建議您在多個作業系統上測試執行緒化程式碼,以驗證它是否真正是跨平臺的。
synchronized() 方法建立了一個模擬鎖定的程式碼塊。這個用同步方法描繪的程式碼只允許每次只有一個程式執行它。但不要使用太多的 synchronized 呼叫,因為它們會直接影響程式碼效能。實際上,同步停止了多執行緒化。
以下顯示了使用同步化方法的程式碼示例。透過重新設定例項變數中表的最大的列大小,這段程式碼將一個元素新增到表中。可以看到多個執行緒更新同一個變數值可能會造成破壞。使用同步化方法有助於緩和這個問題。
/** Synchronized method to add an element to a table **/
public void addElement( Patient newPatient )
{
synchronized ( lock )
{
Log query = incomingPatient.getLog();
results = query.getAllSearchResults();
for ( int k = 0; k < results.length; k++)
{
.... // add to table
setMaxColSize(MyTable);
tableContents.add(MyTable);
}
}
}
避免多執行緒錯誤
有一些方法可以避免可怕的執行緒錯誤:
如果依靠執行緒優先順序來使執行緒保持同步,那麼測試 JVM 的各種類就顯得非常重要。小心可能發生兩個執行緒同時賦值給 long 和 double 變數。其討厭的結果是一個執行緒的更改可能更改某個變數,而第二個執行緒可能再次改變同一個變數。請考慮對那些變數型別進行同步賦值。
永不使用 stop() 方法。實際上,Java 2 中反對該方法。它會立即停止程式,但又不進行整理,這會導致許多問題,包括死鎖和記憶體鎖定。 應始終透過從 run() 方法返回來終止執行緒。
不要重新啟動已停止的執行緒。run() 方法沒有被呼叫,而 isAlive() 方法報告錯誤,指出實際上執行緒已死。
不要獨佔 CPU。如果程式的一部分獨佔了 CPU,就應該執行 yield() 方法,此方法可以讓其它執行緒也有機會執行。請參閱這個小示例:
double answer = 0;
for (int i=0; i<10000; i++) {
for (int j = 0; i<10000; j++) {
answer = ((answer * i) + j) / j;
}
Thread.yield(); // Now other threads may run while this
//runs in the background
}
最有價值的除錯工具是以執行緒為中心的。大部分 Java 錯誤都與執行緒互動有關。多執行緒除錯讓開發人員可以檢視應用程式中執行的每個執行緒中的執行情況。
--------------------------------------------------------------------------------
By Wing, 出處:Laura Bennett
Java除錯教程(六)--多執行緒除錯
SUN Laura Bennett
多執行緒除錯基礎
最有價值的除錯工具是以執行緒為中心的。大部分 Java 錯誤都與執行緒互動有關。多執行緒除錯讓開發人員可以檢視應用程式中執行的每個執行緒中的執行情況。
由於執行順序的易變性,查詢多執行緒應用程式中的錯誤比非執行緒化情況要困難得多。如果可以按相同的可預料順序執行指令,那麼除錯這些應用程式就可以變得非常簡單。當然,這將違背多執行緒化的目標。結果,許多 IDE 偵錯程式在這種情況下都不能起什麼作用,因為單步除錯程式碼會減緩除錯過程,並禁止重新建立錯誤事件。
多執行緒錯誤的型別
這裡有幾種常見的多執行緒編碼問題需要密切關注:
訪問違規。當兩個或更多執行緒試圖訪問同一個記憶體位置時,會發生這種問題。
死鎖。譬如說 Thread1 鎖定了 ResourceA,而 Thread2 鎖定了 ResourceB。然後Thread1試圖鎖定 ResourceB,並等待 ResourceB 變成可用的。同時,Thread2試圖鎖定 ResourceA 並等待 ResourceA 變成可用的。 結果:死鎖。防止死鎖的一種方法是不要讓程式在設定了鎖定時睡眠。還可以使用 synchronization() 來確保關鍵部分的程式碼一次只能由一個執行緒訪問。
資料爭用錯誤。資料爭用條件會鎖定應用程式,這種情況會時常發生,譬如雙擊滑鼠左鍵。在資料爭用的情況下資料通常會遭到破壞。要防止這種錯誤,應使變數不能被多個執行緒訪問。現在已經有工具可以分析這種問題並標誌可能發生資料爭用錯誤的變數。
同步錯誤。進行無用資訊收集時可能會發生這種問題。Java 會自動處理無用資訊收集。此時,所有執行緒都會從執行狀態變成暫掛。
使用 synchronized() 方法
不同版本的 JVM 實現執行緒優先順序的方法也可能不同,這會影響執行緒同步。我們建議您在多個作業系統上測試執行緒化程式碼,以驗證它是否真正是跨平臺的。
synchronized() 方法建立了一個模擬鎖定的程式碼塊。這個用同步方法描繪的程式碼只允許每次只有一個程式執行它。但不要使用太多的 synchronized 呼叫,因為它們會直接影響程式碼效能。實際上,同步停止了多執行緒化。
以下顯示了使用同步化方法的程式碼示例。透過重新設定例項變數中表的最大的列大小,這段程式碼將一個元素新增到表中。可以看到多個執行緒更新同一個變數值可能會造成破壞。使用同步化方法有助於緩和這個問題。
/** Synchronized method to add an element to a table **/
public void addElement( Patient newPatient )
{
synchronized ( lock )
{
Log query = incomingPatient.getLog();
results = query.getAllSearchResults();
for ( int k = 0; k < results.length; k++)
{
.... // add to table
setMaxColSize(MyTable);
tableContents.add(MyTable);
}
}
}
避免多執行緒錯誤
有一些方法可以避免可怕的執行緒錯誤:
如果依靠執行緒優先順序來使執行緒保持同步,那麼測試 JVM 的各種類就顯得非常重要。小心可能發生兩個執行緒同時賦值給 long 和 double 變數。其討厭的結果是一個執行緒的更改可能更改某個變數,而第二個執行緒可能再次改變同一個變數。請考慮對那些變數型別進行同步賦值。
永不使用 stop() 方法。實際上,Java 2 中反對該方法。它會立即停止程式,但又不進行整理,這會導致許多問題,包括死鎖和記憶體鎖定。 應始終透過從 run() 方法返回來終止執行緒。
不要重新啟動已停止的執行緒。run() 方法沒有被呼叫,而 isAlive() 方法報告錯誤,指出實際上執行緒已死。
不要獨佔 CPU。如果程式的一部分獨佔了 CPU,就應該執行 yield() 方法,此方法可以讓其它執行緒也有機會執行。請參閱這個小示例:
double answer = 0;
for (int i=0; i<10000; i++) {
for (int j = 0; i<10000; j++) {
answer = ((answer * i) + j) / j;
}
Thread.yield(); // Now other threads may run while this
//runs in the background
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617731/viewspace-958469/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- gdb多執行緒多程序除錯命令執行緒除錯
- IDEA多執行緒下空指標斷點除錯Idea執行緒指標斷點除錯
- 在IntelliJ IDEA中多執行緒併發程式碼的除錯方法IntelliJIdea執行緒除錯
- [Flutter]啟動:除錯執行Flutter除錯
- 用VBoxDbg除錯並理解單執行緒版髒牛除錯執行緒
- gdb除錯正在執行的程式除錯
- 除錯篇——除錯物件與除錯事件除錯物件事件
- gdb除錯多程序除錯
- 併發程式設計-10.使用 Visual Studio 除錯多執行緒應用程式程式設計除錯執行緒
- Java新特性中的Preview功能如何執行和除錯JavaView除錯
- 給執行緒池取一個名稱有助於除錯 - bozho執行緒除錯
- JVM中jhsdb除錯教程JVM除錯
- Javac 原始碼除錯教程Java原始碼除錯
- Windows windbg kernel debug 雙機核心除錯 - USB3.0 除錯 USB除錯 除錯線Windows除錯
- Idea除錯Rocketmq原始碼編譯執行Idea除錯MQ原始碼編譯
- Java除錯大法,來了~Java除錯
- Node 除錯工具入門教程除錯
- Python 程式碼除錯—使用 pdb 除錯Python除錯
- IsDebuggerPresent的反除錯與反反除錯除錯
- 用VBoxDbg除錯並理解單執行緒版髒牛(CVE-2016-5195)除錯執行緒
- 嗯!這篇多執行緒不錯!伍執行緒
- Java入門教程十三(多執行緒)Java執行緒
- nginx 錯誤除錯Nginx除錯
- Java多執行緒-執行緒中止Java執行緒
- Xcode Instruments除錯swift入門教程XCode除錯Swift
- Google Chrome 除錯JS簡單教程GoChrome除錯JS
- vscode 除錯多個js檔案VSCode除錯JS
- 前端除錯前端除錯
- python 除錯Python除錯
- LLDB除錯LLDB除錯
- postman除錯Postman除錯
- Linux除錯Linux除錯
- 除錯toybox除錯
- gdb除錯除錯
- 【Java多執行緒】輕鬆搞定Java多執行緒(二)Java執行緒
- CLion和WSL配置MPI執行及除錯環境除錯
- cy.visit 執行邏輯的單步除錯除錯
- phpstorm進行動態除錯PHPORM除錯
- Kubernetes 使用arthas進行除錯除錯