(適用Idea 14 & 15,其餘版本未知)java
幾天前遇到一個問題:
在多線程調試的時候,一些斷點會被跳過。多線程
好比像下面的代碼:ide
public static void main(String[] args) throws InterruptedException { new Thread() { // 斷點0 @Override public void run() { System.out.println("1"); // 斷點1 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("2"); // 斷點2 } }.start(); // 外線程 System.out.println("3"); // 斷點3 Thread.sleep(2000); System.out.println("4"); // 斷點4 }
啓動調試後,可能會命中斷點1或者斷點3,命中路徑能夠是3->2->4或者3->4甚至3->2,總之並不會命中所有斷點。在單步調試的過程當中,代碼的執行速度事實上遠比直接運行慢得多,因此我加入了一些sleep用來模擬這些延遲的過程。線程
這段代碼一共有兩個線程,在調試一個線程的過程當中,很顯然另外一個線程是在運行的。因此咱們能夠猜想是否是Idea是否是會在咱們調試一個線程時,屏蔽另外一個線程的斷點。
爲了驗證這個觀點,只須要在命中斷點0處以後單步,就會到斷點3,然會你調試得「慢」一點,就會發現斷點1和2被跳過了。調試
打鉤的是我當前調試的線程(main線程),當你開始單步調試以後,這個堆棧會刷新。code
這顯然是不能接受的,對於多線程調試來講,最重要的就是控制兩個線程的執行順序,咱們要作的其實就是當另外一個不處於調試狀態的線程命中斷點後,能先暫停,一直等到我去處理爲止。圖片
通過一番折騰後發現,其實Idea提供了這個功能,在斷點處右鍵
它提供了兩種掛起的模式,默認的是All,只須要選中Thread,它就會一直等待到你處理它。
右邊的Make Default功能會使得以後打上的斷點也會是Thread模式的(注意,以前打上的不會變動,須要手工更改)。
兩個紅圈的按鈕就能夠改,在Debug窗口的最右邊。io
以後就能夠開心地調試了,對了,在這裏切換線程
class