1. 程式人生 > >在IntelliJ IDEA中多執行緒併發程式碼的除錯方法

在IntelliJ IDEA中多執行緒併發程式碼的除錯方法

通常來說,多執行緒的併發及條件斷點的debug是很難完成的,或許本篇文章會給你提供一個友好的除錯方法。讓你在多執行緒開發過程中的除錯更加的有的放矢。 我們將通過一個例子來學習。在這裡,我編寫了一個多執行緒程式來計算此數學問題:`100! + 100000!`。即:100的階乘 + 100000的階乘。 > 數學不好的同學看這裡,100 階乘就是:1 * 2 * 3 * …… * 100 = ? ,簡寫為100! ~~~ import java.math.BigInteger; public class MathProblemSolver { //開啟兩個執行緒 public static void main(String arg[]){ //第一個執行緒計算 100! FactorialCalculatingThread thread1 = new FactorialCalculatingThread(100); //第二個執行緒計算 100000! FactorialCalculatingThread thread2 = new FactorialCalculatingThread(100000); thread1.setName("Thread 1"); thread2.setName("Thread 2"); thread1.start(); thread2.start(); try { thread1.join(); //執行緒Jion,以使主執行緒在“執行緒1”和“執行緒2”都返回結果之前不會進一步執行 thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } BigInteger result = thread1.getResult().add(thread2.getResult()); System.out.println("將兩個執行緒的計算結果相加等於:" + result); } //用於階乘計算的執行緒類 private static class FactorialCalculatingThread extends Thread { private BigInteger result = BigInteger.ONE; private long num; public FactorialCalculatingThread(long num) { this.num = num; } @Override public void run() { System.out.println(Thread.currentThread().getName() + " 開始階乘的計算:" + num); factorialCalc(num); System.out.println(Thread.currentThread().getName() + "執行完成"); } //數的階乘計算方法 public void factorialCalc(long num) { BigInteger f = new BigInteger("1"); for (int i = 2; i <= num; i++) f = f.multiply(BigInteger.valueOf(i)); result = f; } public BigInteger getResult() { return result; } } } ~~~ 上面的程式碼解釋 * 開啟兩個執行緒,“Thread 1”計算(100!)和“Thread 2”計算(100000!) * 在main()方法中啟動兩個執行緒,然後呼叫`thread1.join()`和`thread2.join()`,以使主執行緒在“執行緒1”和“執行緒2”都返回結果之前不會進一步執行。 * 最後將兩個執行緒的計算結果相加,得到`100! + 100000!` 下面就讓我們使用IntelliJ IDEA工具來除錯這段多執行緒的程式碼。 ## Frames 與 Thread 面板 除錯工具視窗的“*Frames”面板*包含一個下拉選單。它的關注點在:由於斷點而導致暫停的執行緒,並顯示這些執行緒的呼叫堆疊資訊。在下圖中,斷點位於main()方法中如圖所示的位置,Frame向我們顯示了主執行緒的呼叫堆疊。 ![](https://img2020.cnblogs.com/other/1815316/202008/1815316-20200805131641484-1104349097.png) 如果要檢查其他執行緒的呼叫堆疊,則可以從下拉列表中進行選擇。 ![](https://img2020.cnblogs.com/other/1815316/202008/1815316-20200805131641923-429468510.png) *Thread面板*顯示當前處於活動狀態的所有執行緒。參考上面的程式碼,我在`thread1.join()`添加了一個斷點。當應用程式在該斷點處暫停時,我們應該在此窗格中至少看到三個執行緒-“main”,“Thread 1”和“Thread 2”(請看下面的螢幕截圖)。您可以雙擊每個執行緒以觀察其呼叫堆疊。 ![](https://img2020.cnblogs.com/other/1815316/202008/1815316-20200805131642279-684430042.png) ## 條件斷點-只掛起符合條件的執行緒 假設我正在解決該程式中的錯誤,並且我只需要在“Thread 2”開始執行時就暫停執行。這表明我需要在FactorialCalculatingThread的run()方法的第一行上新增一個斷點。因為我們開啟的兩個執行緒使用的是同一段程式碼,所以我們會遇到一個問題-使用該段程式碼的所有執行緒遇到斷點都將被掛起,包括應用程式的“Thread 1”和“Thread 2”。我不希望兩個執行緒都暫停。該怎麼做? 我們可以使用條件斷點功能。新增斷點後,右鍵單擊它,選中“suspend”並選擇“Thread”。然後我們新增條件`currentThread().getName().equals("Thread 2")`,如下面的螢幕快照所示。此條件確保偵錯程式僅在當前執行緒的名稱為“Thread 2”時才暫停當前執行緒: ![](https://img2020.cnblogs.com/other/1815316/202008/1815316-20200805131642590-2075603638.png) 現在執行除錯程式,當應用暫停時,僅“Thread 2”被暫停。您可以通過以下步驟確認“Thread 1”已執行並且沒有被掛起: 1.在控制檯中,您可以通過日誌來驗證“Thread 1”已執行並退出。 ![](https://img2020.cnblogs.com/other/1815316/202008/1815316-20200805131642882-1642119746.png) 2.在“Thread”面板中,可以看到此時已經沒有“Thread 1”,已經執行完成了! ![](https://img2020.cnblogs.com/other/1815316/202008/1815316-20200805131643138-765657390.png) 在不同的IDE版本中,配置條件斷點的方式可能有所不同。但是關鍵思想是要意識到這些功能的存在並加以使用。 ## 歡迎關注我的部落格,裡面有很多精品合集 * 本文轉載註明出處(必須帶連線,不能只轉文字):[字母哥部落格](http://www.zimug.com)。 **覺得對您有幫助的話,幫我點贊、分享!您的支援是我不竭的創作動力!** 。另外,筆者最近一段時間輸出瞭如下的精品內容,期待您的關注。 * [《手摸手教你學Spring Boot2.0》]( https://www.kancloud.cn/hanxt/springboot2/content ) * [《Spring Security-JWT-OAuth2一本通》](https://www.kancloud.cn/hanxt/springsecurity/content) * [《實戰前後端分離RBAC許可權管理系統》](https://www.kancloud.cn/hanxt/vue-spring/content) * [《實戰SpringCloud微服務從青銅到王者》](https://www.kancloud.cn/hanxt/springcloud/content) * [《VUE深入淺出系列》](https://www.kancloud.cn/hanxt/vuejs2/