java - while 循环条件的同步块(synchronized block)

标签 java concurrency synchronized

我正在尝试修复我编写的一段当前存在竞争条件的代码。这样做时,我需要将 while 循环的条件放在 synchronized block 中,但是我不想同步整个 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);
}

这对于可读性来说不太好。有什么建议吗?

最佳答案

尝试如下所示。

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;
}

关于java - while 循环条件的同步块(synchronized block),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38962265/

相关文章:

java - Springboot同步方法

java - 无法将 Date 对象从 React 传递到后端到 Spring Boot

java - 执行器是否意味着被重用?

java - 在java中按需创建数组

java - 使线程以正确的方式工作

Java并发: Modifying latch/ThreadGroup to achieve Executor behaviour

java - 如果我对静态方法进行类级别锁定,并且如果一个线程执行它,那么它会阻止其他线程执行同一类的其他实例方法吗?

java - 使用套接字在 java 同步方法中抛出 NullPointerException

java - 使用 JPA/Hibernate 在集合中搜索

java - 为什么转换方向在原始类型中从大到小,在对象中从小到大?