2016-07-09 109 views
0

此處顯示的for循環在一個線程內運行。在同步塊內部,一個線程寫入某個文件。有幾個不同的文件,所以編寫者保存在一個數組中。我想在這裏確定的是,沒有兩個不同的線程同時寫入同一個文件。但是,他們可以寫入不同的文件。我使用正確的參數與同步塊嗎?這是在Java中使用同步的正確方法嗎?

for(Element e: elements) 
{ 
    int i = getWriterIndex(e) 
    writeri = writers(i) 
    synchronized(writeri) 
    { 
     // Write to corresponding segment 
     writers(i).write(e) 
     recordsWritten(i) += 1 
    } 
} 
+0

你可以包含包含這個'synchronized'塊的方法嗎? –

+0

我已經添加了它,不是方法,而是從其調用的那個循環。 – pythonic

+0

我不是專業人士,但是這種看起來像生產者 - 消費者,你的同步代碼會阻止整個for循環,也許你想爲每個文件使用一個隊列,並將數據發送到相應的隊列,這樣他們可以在自己的線程中寫入相應的文件中。再次,我不是專家,完全沒有。 –

回答

1

雖然我認爲這會起作用,但我強烈建議你避免使用同步。原因在於最終你在同步策略中嚴格要求是很常見的。正如其他人所說,這似乎是一個完美的隊列用例。

如果你不想在大多數情況下使用隊列(包括這個),我會建議使用鎖來保持線程安全(通常爲ReentrantReadWriteLock)。你可以找到一個例子here

在你的情況下,我會創建一個單一的鎖定每個作家,並要求爲了使用作家當前線程必須持有writelock。 (如果你只是寫你可能使用簡單的鎖而不是ReentrantReadWriteLock。

1

是的,只要同步塊僅訪問用作鎖的數據結構,您的同步代碼將按預期工作。所以,在你的代碼中,writeri不能被多個線程同時訪問,所以它是線程安全的。

但是,你必須確保你不訪問變量recordsWritten別的地方,因爲這樣你將有比賽條件。所以,理想情況下你也可以鎖定這個變量(在你訪問它的每個地方),或者你可以使用一些Java原語,例如AtomicInteger

相關問題