don't use unsafe to update nextName#1892
Conversation
| } | ||
|
|
||
| @nowarn @volatile private var _nextNameDoNotCallMeDirectly = 0L | ||
| private val _nextName = new java.util.concurrent.AtomicLong() |
There was a problem hiding this comment.
better go with AtomicLongFieldUpdater.
There was a problem hiding this comment.
I tried AtomicLongFieldUpdater but it doesn't work with private fields.
[error] Caused by: java.lang.IllegalAccessException: class example.AbstractActorCell cannot access a member of class example.ActorCell with modifiers "private volatile"
I also found in benchmarks that AtomicLong is nearly as fast as the existing code and the code is much simpler to maintain. No reflection, no sun.misc.Unsafe.
There was a problem hiding this comment.
I actually got AtomicLongFieldUpdater to work by moving the code to be in the class that has the private field. The performance in my bench testing is no better than the simpler AtomicLong.
There was a problem hiding this comment.
AtomicLongFieldUpdater can save memory
There was a problem hiding this comment.
AtomicLongFieldUpdater is slower in my testing
|
Track upstream: scala/scala3#9013 |
|
User can use |
| } | ||
|
|
||
| @nowarn @volatile private var _nextNameDoNotCallMeDirectly = 0L | ||
| private val _nextName = new java.util.concurrent.atomic.AtomicLong() |
There was a problem hiding this comment.
We should use the *Updater here, see http://normanmaurer.me/blog/2013/10/28/Lesser-known-concurrent-classes-Part-1/
There was a problem hiding this comment.
this article is 12 years old. Java runtimes and their memory allocation have improved a lot since then.
There was a problem hiding this comment.
even netty uses AtomicLongs
https://github.com/search?q=repo%3Anetty%2Fnetty%20atomiclong&type=code
It also uses the FieldUpdater in a few places but the Netty team seem to believe that the FieldUpdater doesn't need to be used in every case.
There was a problem hiding this comment.
That's not true, it's still valid, you can test it with jol.
|
I've tried a few ways to get AtomicLongFieldUpdater to work but so far no look. AtomicLongFieldUpdater does runtime checks and can only access fields in the same class or public variables - but we can't make the long public because then it could be manipulated by any code and it isn't good to have a AtomicLongFieldUpdater declared in the Children trait because you get one instance per ActorCell. I tried using a companion object but in Java that's a separate class and you can't then access a private field in another class. |
mdedetrich
left a comment
There was a problem hiding this comment.
Instead of asInstanceOf[Long] use : Long instead i.e.
val num = AbstractActorCell.nextNameHandle.getAndAdd(this, 1L).asInstanceOf[Long]should be
val num = AbstractActorCell.nextNameHandle.getAndAdd(this, 1L): Longval num: Long = AbstractActorCell.nextNameHandle.getAndAdd(this, 1L)Might also work.
The reason is that using val num: Long or : Long on the right hand side of the expression is a type ascription which means it completely avoids a runtime call (as long as the expression satisfies the compiler), see https://www.baeldung.com/scala/type-casting#type-ascriptions
mdedetrich
left a comment
There was a problem hiding this comment.
lgtm (pending CI pass). Left one additional comment, not critical but it looks a bit sus.
|
Netty recently using varhandle |
Uh oh!
There was an error while loading. Please reload this page.