News for hackers. Stuff that matters.
Re:JVM Anatomy Quarks by wiradikusuma on Friday January 31, 2020 @04:22AM (#22200256)
Man, I always use String.intern() for synchronized(theString). -- https://shipilev.net/jvm/anatomy-quarks/10-string-intern/
Re:JVM Anatomy Quarks by xxs on Friday January 31, 2020 @11:09AM (#22202757)
Sync on a string is a bad to boot.

It's hard to explain how terrible the idea to synchronize/lock objects you don't control.

As for interning (not for strings only and not guaranteed) I have a lock free table (not CHM) that keeps most used objects (with possible random eviction) to provide a good trade off between unnecessary memory waste, fast access and low memory footprint.

Re:JVM Anatomy Quarks by diroussel on Friday January 31, 2020 @08:20AM (#22201411)
If need to synchronise() and there is not an obvious choice then I create a new Object() for that purpose and make sure it’s available wherever locking is needed (ideally encapsulated in one class)
Re:JVM Anatomy Quarks by sorokod on Friday January 31, 2020 @10:01AM (#22202163)
The ReentrantLock class and friends have been around for a while and typically provide a better alternative.
Re:JVM Anatomy Quarks by xxs on Friday January 31, 2020 @11:25AM (#22202896)
Nowadays (java 7/8), "synchronize" is likely better than most uses of reentrant lock, though. It's especially good in (common) cases where the lock is not contended.

even CHM uses synchronized nowadays.

Flip note: don't touch ReadWriteLocks

Re:JVM Anatomy Quarks by diroussel on Saturday February 01, 2020 @05:11AM (#22209748)
In the past I have followed this approach myself. But that is changing. If you want to future proof your code, don't use classic locks. Project Loom doesn't work with classic locks, and the java.nio package is has been re-written to remove classic locks:

> In Project Loom, there will be support for efficiently switching between fibers that use Java 5 locks (that is, the java.util.concurrent.lock package) but not native C locks. As a result, it is necessary to migrate all blocking code in the JDK over to Java 5 locks. So the legacy Socket API required reimplementation to achieve better compatibility with Project Loom.

See: https://blogs.oracle.com/javamagazine/inside-java-13s-switch...

Re:JVM Anatomy Quarks by sorokod on Friday January 31, 2020 @12:20PM (#22203444)
> don't touch ReadWriteLocks

I am interested in references that back this statement

Re:JVM Anatomy Quarks by MrBuddyCasino on Friday January 31, 2020 @04:12PM (#22205792)
I was interested in this as well, and yes ReadWriteLocks are horrible[0]. Just using synchronized is a good default that performs well in most scenarios, StampedLocks are good too.

[0] https://blog.overops.com/java-8-stampedlocks-vs-readwriteloc...

Re:JVM Anatomy Quarks by xxs on Friday January 31, 2020 @06:51PM (#22207222)
About the blog - testing with more threads than cores could be quite misleading, also testing on dual/quad socket vs single one exhibits the effects on coherency traffic a lot more (compared to L3 talk)
Re:JVM Anatomy Quarks by xxs on Friday January 31, 2020 @06:48PM (#22207198)
Briefly:

- the lock has write a CAS on the =fast= read path, causing coherency traffic and a contention point between the readers. That's it the readers don't scale

- it's quite hard to use correctly, i.e. after read, determining the exclusive/write lock has to be acquired, the read lock has to be released 1st, the write lock acquired and the conditions that causes the grab to be rechecked

- Copy-On-Write should be a preferred solution for most cases, easy to understand and reason about. If not StampedLock is a better alternative.

Re:JVM Anatomy Quarks by jabba_d_hut on Friday January 31, 2020 @02:24PM (#22204695)
StampedLocks performs much better than R/W locks.
Re:JVM Anatomy Quarks by hyperpape on Friday January 31, 2020 @09:02AM (#22201700)
Aside from String.intern() being dubious, if you synchronized on an interned string, anything else that happens to work with an interned copy of that string is now contending with your lock. In the worst case, you could deadlock.

If you really need this sort of dynamic locking, you can use a ConcurrentHashMap<String, Object> to achieve it (lock on the object). I'm not sure whether it's ever the _best_ design, but it avoids interning the string, and it keeps an anonymous lock object that you know won't be shared.

Re:JVM Anatomy Quarks by chrisseaton on Friday January 31, 2020 @09:54AM (#22202094)
> anything else that happens to work with an interned copy of that string is now contending with your lock

Isn't that the point?

People use it to create symbolic locks in situations where they don't want to use any more formal link of linkage provided by the JVM. In your case you need some way to get a handle to that concurrent hash map, so some kind of formal JVM linkage. Sometimes that's hard.

Not saying how it's how I'd chose to design an application, but I presume people doing this have their own good reasons.

Re:JVM Anatomy Quarks by hyperpape on Friday January 31, 2020 @01:34PM (#22204154)
I think there's a subtle difference: you want to create mutual exclusion around specific operations using that string. However, it's at least conceivable that something else uses the interned instance of that string, and thereby creates contention.

Now, if your string is sufficiently unique, the chances are relatively low, as long as you don't leak a reference to it (an object, or explicit Lock only has one purpose, so that's less likely).

Still, it's basically mysterious action at a distance. Whereas using the ConcurrentHashMap, it's very explicit action at a distance. Granted, it does require explicit JVM linkage, which is a cost.

Re:JVM Anatomy Quarks by sk5t on Friday January 31, 2020 @09:53AM (#22202084)
Yeah--mucking about with .intern for no good reason, or locking on strings in general, shouldn't pass a code review, this reeks of sticking one's fingers in all sorts of places they don't belong. ConcurrentHashMap.computeIfAbsent (and computing a value that is _not_ subject to mysterious external forces) is so much better.
Re:JVM Anatomy Quarks by xxs on Friday January 31, 2020 @11:21AM (#22202853)
>ConcurrentHashMap.computeIfAbsent

It's leak prone as it'd hold the references forever. It's a cheap and easy way to do it but far from ideal. I'd not recommend it.

Re:JVM Anatomy Quarks by sk5t on Friday January 31, 2020 @08:05PM (#22207738)
This seems a strange criticism--of course entries in a map don't disappear for no reason at all. Consider using an atomic cache if you are going to stick so many keys into the map that it becomes an issue. Or else bucket the keys into a known set, if you can tolerate the occasional collision.
Re:JVM Anatomy Quarks by xxs on Saturday February 01, 2020 @05:19AM (#22209768)
String.intern does remove references (it used not to and it was considered a major issue). Imagine parsing documents and keeping the words - it works well as long as the input is not malicious. Otherwise words would pile up with no one cleaning them, give it enough time/input to slow the application due to memory pressure, crashing with OOM.
Re:JVM Anatomy Quarks by aardvark179 on Friday January 31, 2020 @05:25AM (#22200542)
I hesitate to ask what exactly you’re trying to achieve locking On a string which you have to intern like that. There may well be a different design that would avoid having to do it.
Re:JVM Anatomy Quarks by vbezhenar on Friday January 31, 2020 @08:54AM (#22201630)
Avoiding this pattern is surprisingly hard to get right.