while 循环条件的同步块
synchronized block for a while loop's condition
我正在尝试修复我编写的一段目前存在竞争条件的代码。在这样做时,我需要将 while
循环的条件放在 synchronized
块中,但是我不想同步整个 while
块,因为这会使其他线程饿死资源,他们需要的。如果不重复或 break
s 在稍微模糊控制流的地方,我想不出一个合理的方法。以下是问题代码的要点:
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);
}
这不利于可读性。有什么建议吗?
像下面这样尝试。
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;
}
我正在尝试修复我编写的一段目前存在竞争条件的代码。在这样做时,我需要将 while
循环的条件放在 synchronized
块中,但是我不想同步整个 while
块,因为这会使其他线程饿死资源,他们需要的。如果不重复或 break
s 在稍微模糊控制流的地方,我想不出一个合理的方法。以下是问题代码的要点:
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);
}
这不利于可读性。有什么建议吗?
像下面这样尝试。
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;
}