2016-08-15 71 views
0

我試圖修復一段我寫的代碼,目前有競爭條件。在這樣做時,我需要將while循環的條件放在​​塊中,但是我不想同步整個while塊,因爲這會使資源的其他線程捱餓,而這些線程都是他們需要的。我無法找到一個合理的方式,在沒有重複的情況下或者在略微模糊控制流的地方進行。下面的問題是代碼的要點:while循環的條件的同步塊

while ((numRead = in.read(buffer)) != -1) { 
    out.write(buffer); 
} 

,我需要使用in同步。我能想到的(但不認爲他們是非常好的)兩個可能的解決方案是:

synchronized (this) { 
    numRead = in.read(buffer); 
} 
while (numRead != -1) { 
    out.write(buffer); 
    synchronized (this) { 
     numRead = in.read(buffer); 
    } 
} 

具有不良的重複,這:

while (true) { 
    synchronized (this) { 
     numRead = in.read(buffer); 
    } 
    if (numRead == -1) 
     break; 
    else 
     out.write(buffer); 
} 

這是不是偉大的可讀性。有什麼建議麼?

+1

你可以換行讀取調用的方法調用與同步塊(或方法本身可以同步) – mszymborski

+0

@mszymborski你說的很對,我覺得睡眠不足已開始顯現!謝謝。 –

+2

我沒有得到什麼「同步使用」應該完成。如果不是這樣,你有一個線程從流中讀取並插入到多個使用者使用的阻塞隊列中? –

回答

1

像下面這樣試試。

public testMyMethod() { 
    byte[] buffer = new int[1024]; 
    int numRead = -1; 
    while ((numRead = readInput(buffer)) != -1) { 
     out.write(buffer); 
    } 
} 

//first method 
int readInput(byte[] buffer) { 
    int readLen = -1; 
    synchronized(in) { 
     in.read(buffer); 
    } 
    return readLen; 
} 

//second method, more performant about 3 times, just the synchronization parts 
private static final ReentrantLock inputLock = new ReentrantLock(); 

int readInput(byte[] buffer) { 
    int readLen = -1; 
    inputLock.lock(); 
    try { 
     readLen = in.read(buffer); 
    } finally { 
     inputLock.unlock(); 
    } 
    return readLen; 
} 
+0

我對你說'ReentrantLock'比'synchronized'塊快3倍的部分非常感興趣。這是一個大膽的說法。您是否有任何支持該聲明的來源/參考,還是基於您自己的基準? – sstan

+0

兩者都不會在'in'中同步(但是可能還會根據同步的原因進行相應的修改) – eckes

+0

@sstan它肯定是不正確的,無約束同步是儘可能快的。 – eckes