spring-cloud-commons icon indicating copy to clipboard operation
spring-cloud-commons copied to clipboard

LockedScopedProxyFactoryBean have some problems in heavy concurrency contention on ReadWriteLock

Open anLA7856 opened this issue 5 years ago • 1 comments

Describe the bug I found the scope of refresh bean will be destroied when a RefreshScopeRefreshedEvent calls, this operation will compete for the writelock of ReentrantReadWriteLock. Wihle other reader threads access any method of this bean,they will compete for the readlock of the same ReentrantReadWriteLock. If one reader threads which has the readlock is slow or dead cycle, when access this bean, at this time, one thread sends an RefreshScopeRefreshedEvent and trys to aquire writelock. Besides, a large mount of threads access some method of this bean, and these thread will be parked until the write-thread has been done.

I think the refresh of refresh scope bean shouldn't block other reader threads. Others can do their things on the previous bean instance.

Sample I write a demo about this use of ReentrantReadWriteLock in this situation.

        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        Thread threadPark = new Thread(() -> {
            Lock readLock = lock.readLock();
            readLock.lock();
            try {
                while (true){
                    System.out.println("I have the read lock!! But I wan not to give it you");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }finally {
                readLock.unlock();
            }
        });
        Thread threadWrite = new Thread(() -> {
            Lock writeLock = lock.writeLock();
            writeLock.lock();
            try {
                System.out.println("I have the write lock!!!!");
            }finally {
                writeLock.unlock();
            }
        });
        Thread threadRead = new Thread(() -> {
            Lock readLock = lock.readLock();
            readLock.lock();
            try {
                System.out.println("I have the read lock!!!!");
            }finally {
                readLock.unlock();
            }
        });
        threadPark.start();
        Thread.sleep(2000);
        threadWrite.start();
        Thread.sleep(2000);
        threadRead.start();

Solution Can we use StampLock to replace the ReentrantReadWriteLock?

anLA7856 avatar May 13 '20 15:05 anLA7856

PRs welcome

spencergibb avatar Jul 06 '20 15:07 spencergibb