在IntelliJ IDEA中多線程并發(fā)代碼的調(diào)試方法詳解
通常來說,多線程的并發(fā)及條件斷點的debug是很難完成的,或許本篇文章會給你提供一個友好的調(diào)試方法。讓你在多線程開發(fā)過程中的調(diào)試更加的有的放矢。
我們將通過一個例子來學(xué)習(xí)。在這里,我編寫了一個多線程程序來計算此數(shù)學(xué)問題:100! + 100000!
。即:100的階乘 + 100000的階乘。
數(shù)學(xué)不好的同學(xué)看這里,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”都返回結(jié)果之前不會進一步執(zhí)行 thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } BigInteger result = thread1.getResult().add(thread2.getResult()); System.out.println("將兩個線程的計算結(jié)果相加等于:" + 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() + "執(zhí)行完成"); } //數(shù)的階乘計算方法 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?。┖汀癟hread 2”計算(100000!)
- 在main()方法中啟動兩個線程,然后調(diào)用
thread1.join()
和thread2.join()
,以使主線程在“線程1”和“線程2”都返回結(jié)果之前不會進一步執(zhí)行。 - 最后將兩個線程的計算結(jié)果相加,得到
100! + 100000!
下面就讓我們使用IntelliJ IDEA工具來調(diào)試這段多線程的代碼。
Frames 與 Thread 面板
調(diào)試工具窗口的“Frames”面板包含一個下拉菜單。它的關(guān)注點在:由于斷點而導(dǎo)致暫停的線程,并顯示這些線程的調(diào)用堆棧信息。在下圖中,斷點位于main()方法中如圖所示的位置,F(xiàn)rame向我們顯示了主線程的調(diào)用堆棧。
如果要檢查其他線程的調(diào)用堆棧,則可以從下拉列表中進行選擇。
Thread面板顯示當(dāng)前處于活動狀態(tài)的所有線程。參考上面的代碼,我在thread1.join()
添加了一個斷點。當(dāng)應(yīng)用程序在該斷點處暫停時,我們應(yīng)該在此窗格中至少看到三個線程-“main”,“Thread 1”和“Thread 2”(請看下面的屏幕截圖)。您可以雙擊每個線程以觀察其調(diào)用堆棧。
條件斷點-只掛起符合條件的線程
假設(shè)我正在解決該程序中的錯誤,并且我只需要在“Thread 2”開始運行時就暫停執(zhí)行。這表明我需要在FactorialCalculatingThread的run()方法的第一行上添加一個斷點。因為我們開啟的兩個線程使用的是同一段代碼,所以我們會遇到一個問題-使用該段代碼的所有線程遇到斷點都將被掛起,包括應(yīng)用程序的“Thread 1”和“Thread 2”。我不希望兩個線程都暫停。該怎么做?
我們可以使用條件斷點功能。添加斷點后,右鍵單擊它,選中“suspend”并選擇“Thread”。然后我們添加條件currentThread().getName().equals("Thread 2")
,如下面的屏幕快照所示。此條件確保調(diào)試器僅在當(dāng)前線程的名稱為“Thread 2”時才暫停當(dāng)前線程:
現(xiàn)在執(zhí)行調(diào)試程序,當(dāng)應(yīng)用暫停時,僅“Thread 2”被暫停。您可以通過以下步驟確認“Thread 1”已執(zhí)行并且沒有被掛起:
1.在控制臺中,您可以通過日志來驗證“Thread 1”已運行并退出。
2.在“Thread”面板中,可以看到此時已經(jīng)沒有“Thread 1”,已經(jīng)運行完成了!
在不同的IDE版本中,配置條件斷點的方式可能有所不同。但是關(guān)鍵思想是要意識到這些功能的存在并加以使用。
總結(jié)
到此這篇關(guān)于在IntelliJ IDEA中多線程并發(fā)代碼的調(diào)試方法的文章就介紹到這了,更多相關(guān)IDEA多線程并發(fā)代碼的調(diào)試內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Mvc下實現(xiàn)以文件流方式下載文件的方法示例
這篇文章主要介紹了Spring Mvc下實現(xiàn)以文件流方式下載文件的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-05-05Spring boot + LayIM + t-io 實現(xiàn)文件上傳、 監(jiān)聽用戶狀態(tài)的實例代碼
這篇文章主要介紹了Spring boot + LayIM + t-io 實現(xiàn)文件上傳、 監(jiān)聽用戶狀態(tài)的實例代碼,需要的朋友可以參考下2017-12-12基于 SASL/SCRAM 讓 Kafka 實現(xiàn)動態(tài)授權(quán)認證的方法
在大數(shù)據(jù)處理和分析中?Apache Kafka?已經(jīng)成為了一個核心組件,本文將從零開始部署?ZooKeeper?和?Kafka?并通過配置?SASL/SCRAM?和?ACL(訪問控制列表)來增強?Kafka?的安全性,需要的朋友可以參考下2024-07-07mybatis-plus update更新操作的三種方式(小結(jié))
本文主要介紹了mybatis-plus update更新操作的三種方式,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10