简体   繁体   English

Java 中的线程 | 等待(),通知()和通知所有()

[英]Threads in Java | wait(), notify() and notifyAll()

I have an interface as below(assume it's a Java Interface and methods with void return types)我有一个如下接口(假设它是一个 Java 接口和具有 void 返回类型的方法)

interface FileAccessOperations{
    fun requestReadAccess()
    fun releaseReadAccess()
    fun requestWriteAccess()
    fun releaseWriteAccess()
}

Now I have to implement these methods where I need to manage single file's read/write permission between large number of threads.现在我必须实现这些方法,我需要在大量线程之间管理单个文件的读/写权限。

I have implemented as below.我已经实现如下。

public class FileOperationsImpl implements FileAccessOperations {

    /* When count is
     * (equals 0) -> File is free, no thread is accessing it (Write and read request is possible)
     * (greater than 0) -> File is being read by #count of threads.(Reads are still possible. No write)
     * (lesser than 0) -> File is in write mode.(Write/Read is not possible)
     *
     * So basically, the file can read by multiple threads at a time.
     * But only one thread can write at a given time.
     */
    private int count = 0;

    @Override
    synchronized public void requestReadAccess() {
        while(count < 0){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        count++;
    }

    @Override
    synchronized public void releaseReadAccess() {
        if(count > 0){
            count--;
        }
        if(count == 0){
            notifyAll();
        }
    }

    @Override
    synchronized public void requestWriteAccess() {
        while(count != 0){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        count--;
    }

    @Override
    synchronized public void releaseWriteAccess() {
        count = 0;
        notifyAll();
    }
}

Did I do it right?我做对了吗?

I see several issues with your implementation:我发现您的实施存在几个问题:

  1. releaseReadAccess does not check if any read access is actually held, and thus can acquire write access (make count go negative). releaseReadAccess不检查是否实际持有任何读访问,因此可以获得写访问(使count go 为负)。

  2. releaseWriteAccess has a similar problem, it can increase count beyond 0, creating false read lock. releaseWriteAccess也有类似的问题,它可以将计数增加到 0 以上,创建假读锁。

  3. If requestWriteAccess is called while any lock exists, it will block until lock is released, but then do nothing.如果在任何锁存在时调用requestWriteAccess ,它将阻塞直到锁被释放,然后什么也不做。
    Since this function does not return any value, the calling thread will never know it didn't actually get the lock.由于这个 function 没有返回任何值,调用线程永远不会知道它实际上没有获得锁。

  4. Similar issue with requestReadAccess - it will wait until it can grant the lock, but won't increment count , so no lock will be granted. requestReadAccess的类似问题 - 它会等到它可以授予锁,但不会增加count ,因此不会授予锁。

Generally speaking, it is a better design practice to have request functions return true or false to indicate weather lock was successfully obtained, even if they block, just in case there are some error conditions.一般来说,最好让request函数返回truefalse以指示天气锁已成功获得,即使它们被阻塞,以防万一出现一些错误情况,这是一个更好的设计实践。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM