2016-08-15 72 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