5 ms·
Every time, without fail, somebody shows a bug about a piece of code that we take for granted (In this case, the String class) the bug is related to concurrent
by m_0x 3y ago
Every time, without fail, somebody shows a bug about a piece of code that we take for granted (In this case, the String class) the bug is related to concurrent modifications.
Concurrency is so hard that even OpenJDK developers can't prevent these kind of bugs
- singron 3y agoGo has trouble with this too. You can cause undefined behavior with completely safe code by making concurrent modifications to a fat pointer. The writes won't be atomic, and the pointer can be interpreted as the wrong type. E.g. in this example, the B.foo method will be called with a C value as the receiver, which tricks it into accessing memory at 0x1000 and segfaulting, but you could also arbitrarily access any memory this way without using unsafe. https://go.dev/play/p/y4z_vs-I1jb https://go.dev/play/p/y4z_vs-I1jb
- bill3478 3y agoIs not that OpenJDK developers can't prevent these, but there's a forbidding cost for doing so. The simplest "safe" way of doing this involves defensively copying the input argument. However, the `compress` function will likely make yet another smaller copy, making the constructor very allocation and CPU intensive. In fact, due to the fixed array size in Java, all thread-safe implementations must either allocate two arrays to hold the two possible encodings, which guarantees one piece of garbage, or iterating the input array twice. For such a core class like String, this is probably unacceptable cost. And the constructor is not documented to be thread-safe, so no one should expect it to. In reality, there are much more impactful data structures to abuse in Java.