2014-10-16 56 views
1

我想使用線程增加一行矩陣中的數字+1。當線程訪問時,矩陣不能很好地打印

  • 兩個線程不能同時
  • 兩個紗線可以在同一時間

我寫訪問不同排在同一行訪問的是(只有共享資源的方法):

public void increaseRow(Integer row) { 
     if (!mapForRow.containsKey(row)) 
      mapForRow.put(row, "not increased"); 
     if (mapForRow.get(row).equals("not increased")) { 
      lock.lock(); 
      try { 
       while (rowIncreased) { 
        condition.await(); 
       } 
       mapForRow.get(row).equals("increased"); 
       rowIncreased = true; 
       for (int j = 0; j < matrix.length; j++) 
        setMatrix(row, j, matrix[row][j] + 1); 
       rowIncreased = false; 
       // replace the value 
       mapForRow.get(row).equals(" not increased"); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } finally { 
       System.out.println(); 
       System.out.println("begin print matrix"); 
       for (int i = 0; i < row; i++) { 
        System.out.println(); 
        for (int j = 0; j < column; j++) 
         System.out.print(matrix[i][j]); 
       } 
       System.out.println(); 
       System.out.println("end print matrix "); 
       System.out.println(); 
       lock.unlock(); 
       condition.notifyAll(); 
      } 
     } 
    } 

矩陣被初始化爲10行10列,開始線程也是10

而是通過輸出I」 M得到這個:

begin print matrix 

0000000000 
0000000000 
0000000000 
0000000000 
end print matrix 


begin print matrix 

00Exception in thread "Thread-0" 00000000 
0000000000 
0000000000 
end print matrix 

java.lang.IllegalMonitorStateException 
[...] 

我能理解拋出的異常,但爲什麼矩陣沒有完全顯示?

回答

2

爲什麼不使用AtomicInteger。這些可以從多個線程安全地訪問和操作,而不需要鎖定。

如果你想象你的代碼在//開始的行之間,你可以看到,NullPointerException將在鎖定到位時被捕獲和處理,但是如果有任何其他異常被拋出,在那個塊中,異常會在堆棧跟蹤上前進,直到被捕獲,並且當它被捕獲時,你的鎖定將會被釋​​放。

try { 

    // start of your code 
    lock.lock(); 
    try { 
    doStuff(); 
    } catch(InterruptedException e) { 
    System.out.println("in lock"); 
    } finally { 
    lock.unlock(); 
    } 

    // end of your code 

} catch(Exception e) { // IllegalMonitorStateException caught here 
    System.out.println("not in lock"); 
} 
+0

謝謝你的回答,我會試試看。但是,你能解釋一下爲什麼線程中斷他們的打印? – 2014-10-16 10:34:42

+0

該異常似乎被未捕獲的異常處理程序捕獲,而不是由您的代碼塊中的異常處理程序捕獲。因此,當你的finally鎖被 – PeterK 2014-10-16 10:37:09

+0

鎖釋放時,它不是nullPointException,而是IllegalMonitorStateException,如果你看到鎖和解鎖在try-catch-finally塊中。 – 2014-10-16 11:35:04