在IntelliJ IDEA中多線程併發代碼的調試方法

一般來講,多線程的併發及條件斷點的debug是很難完成的,或許本篇文章會給你提供一個友好的調試方法。讓你在多線程開發過程當中的調試更加的有的放矢。vue

咱們將經過一個例子來學習。在這裏,我編寫了一個多線程程序來計算此數學問題:100! + 100000!。即:100的階乘 + 100000的階乘。java

數學很差的同窗看這裏,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; }
    }
}

上面的代碼解釋spring

  • 開啓兩個線程,「Thread 1」計算(100!)和「Thread 2」計算(100000!)
  • 在main()方法中啓動兩個線程,而後調用thread1.join()thread2.join(),以使主線程在「線程1」和「線程2」都返回結果以前不會進一步執行。
  • 最後將兩個線程的計算結果相加,獲得100! + 100000!

下面就讓咱們使用IntelliJ IDEA工具來調試這段多線程的代碼。後端

Frames 與 Thread 面板

調試工具窗口的「Frames」面板包含一個下拉菜單。它的關注點在:因爲斷點而致使暫停的線程,並顯示這些線程的調用堆棧信息。在下圖中,斷點位於main()方法中如圖所示的位置,Frame向咱們顯示了主線程的調用堆棧。springboot

若是要檢查其餘線程的調用堆棧,則能夠從下拉列表中進行選擇。多線程

Thread面板顯示當前處於活動狀態的全部線程。參考上面的代碼,我在thread1.join()添加了一個斷點。當應用程序在該斷點處暫停時,咱們應該在此窗格中至少看到三個線程-「main」,「Thread 1」和「Thread 2」(請看下面的屏幕截圖)。您能夠雙擊每一個線程以觀察其調用堆棧。併發

條件斷點-只掛起符合條件的線程

假設我正在解決該程序中的錯誤,而且我只須要在「Thread 2」開始運行時就暫停執行。這代表我須要在FactorialCalculatingThread的run()方法的第一行上添加一個斷點。由於咱們開啓的兩個線程使用的是同一段代碼,因此咱們會遇到一個問題-使用該段代碼的全部線程遇到斷點都將被掛起,包括應用程序的「Thread 1」和「Thread 2」。我不但願兩個線程都暫停。該怎麼作?前後端分離

咱們可使用條件斷點功能。添加斷點後,右鍵單擊它,選中「suspend」並選擇「Thread」。而後咱們添加條件currentThread().getName().equals("Thread 2"),以下面的屏幕快照所示。此條件確保調試器僅在當前線程的名稱爲「Thread 2」時才暫停當前線程:ide

如今執行調試程序,當應用暫停時,僅「Thread 2」被暫停。您能夠經過如下步驟確認「Thread 1」已執行而且沒有被掛起:微服務

1.在控制檯中,您能夠經過日誌來驗證「Thread 1」已運行並退出。

2.在「Thread」面板中,能夠看到此時已經沒有「Thread 1」,已經運行完成了!

在不一樣的IDE版本中,配置條件斷點的方式可能有所不一樣。可是關鍵思想是要意識到這些功能的存在並加以使用。

歡迎關注個人博客,裏面有不少精品合集

  • 本文轉載註明出處(必須帶鏈接,不能只轉文字):字母哥博客

以爲對您有幫助的話,幫我點贊、分享!您的支持是我不竭的創做動力! 。另外,筆者最近一段時間輸出了以下的精品內容,期待您的關注。

相關文章
相關標籤/搜索