spring-cloud / spring-cloud/spring-cloud-commons
LockedScopedProxyFactoryBean have some problems in heavy concurrency contention on ReadWriteLock
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 751
- Forks
- 744
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 9
Description
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?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at LockedScopedProxyFactoryBean and the RefreshScopeRefreshedEvent path, then reproduce the contention with the ReentrantReadWriteLock sample in the issue. Investigate whether refresh can proceed without parking reader threads; done means the reported concurrency behavior is addressed and the relevant behavior is covered by a test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 28/100