-
Notifications
You must be signed in to change notification settings - Fork 13
Replace synchronized blocks with ReentrantLocks for virtual thread support #102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace synchronized blocks with ReentrantLocks for virtual thread support #102
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let’s see if such an action is really necessary is those cases: https://mikemybytes.com/2024/02/28/curiosities-of-java-virtual-threads-pinning-with-synchronized/!
In other words: if there is really no blocking operation inside that synchronized
, no reason to change it. Plus it looks like some changes are coming to Java down the road : https://openjdk.org/jeps/491
@artembilan Thank you very much for all the valuable information you provided. The links you provided contain really great information. I will read the links you sent again and again; they are really great. However, I believe that |
Sure! I’ll give it a second look when back from vacation next week . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, add your name to the @author
list of the affected classes.
...ain/java/org/springframework/cloud/fn/consumer/cassandra/CassandraConsumerConfiguration.java
Outdated
Show resolved
Hide resolved
/** | ||
* Flag to say that the repository lists traces in reverse order. | ||
* @param reverse flag value (default true) | ||
*/ | ||
public void setReverse(boolean reverse) { | ||
synchronized (this.traces) { | ||
try { | ||
this.tracesLock.lock(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need any locking in setters at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@artembilan I think locking is necessary here because the add method on line 86 uses the reverse and capacity values. In the add method, additions and removals are performed on the traces list using the reverse and capacity values.
add method requires locking, as any changes to reverse or capacity while the add method is being called could result in an inconsistent state. So, we need to lock both the add method and any other parts of the code that can modify the traces and reverse variables used by the add method. Therefore, I believe we should continue using locking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What you are explaining is correct, but that's not realistic.
This class is created only once on Application context initialization.
Those setters are called at this point and only once.
Calling them at runtime is really mocking of the lifecycle of the instance of this class.
We should just agree that we are in Spring, so there are some undocumented rules for singleton beans where we just initialize them once. Plus the instance of this class is created by the configuration in this module.
You just need to drop the jar into your classpath - and everything will be auto-configured for you.
Why do we need the extra logic which may not have power in 99% of usage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, I understand what you mean. Thank you. In that case, I will remove both the lock and the synchronized.
} | ||
|
||
public List<Trace> findAll() { | ||
synchronized (this.traces) { | ||
try { | ||
this.tracesLock.lock(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't look like this operation needs any locking at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@artembilan I think the same way here as well; we shouldn’t remove the locking from this part either.
...main/java/org/springframework/cloud/fn/consumer/websocket/trace/InMemoryTraceRepository.java
Outdated
Show resolved
Hide resolved
/** | ||
* Flag to say that the repository lists traces in reverse order. | ||
* @param reverse flag value (default true) | ||
*/ | ||
public void setReverse(boolean reverse) { | ||
synchronized (this.traces) { | ||
this.tracesLock.lock(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You just removed our conversion on the matter, but still left lock in the setter.
🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once our conversation is finished, I was going to remove them. I'll take care of it right away.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But that conversation has not been finished.
You just didn't wait for my response.
I am the owner of the project, that the final decision is on me.
Please, don't remove any conversation: it will be helpful in the future when some one would try to figure out what was an origin of this or that code.
Like exactly someone would ask why the synchronized
as removed here and lock not added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just thought I would make another commit after our conversation. Of course, I’ll follow your guidelines. I didn’t mean to do anything wrong, sorry if I caused any confusion.
@artembilan I've applied the changes you recommended. And thank you for your guidance. |
b7cf573
to
d4cfb37
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All good, but I cannot merge it yet until I cut 5.0.x
branch.
We are planning to release 5.1.0
soon enough.
Thank you!
Thank you very much for everything. Best regards. |
@omercelikceng , |
Replace synchronized methods and blocks with ReentrantLocks in a few classes in Spring Functions Catalog to improve compatibility with virtual threads. This changes the synchronization mechanism in:
CassandraConsumerConfiguration.PayloadToMatrixTransformer
InMemoryTraceRepository
The change helps avoid blocking virtual threads when using Spring Functions Catalog in Project Loom environments while maintaining thread safety.