Hacker News new | ask | show | jobs
by bsder 481 days ago
Does a ConcurrentSkipListMap not give the correct O(log N) guarantees on top of being concurrency friendly?

java.util.concurrent is one of the best libraries ever. If you do something related to concurrency and don't reach for it to start, you're gonna have a bad time.

2 comments

It's often a better design if you manage the concurrency in a high-level architecture and not have to deal with concurrency at the data structure level.
Designing your own concurrency structures instead of using ones designed by smart people who thought about the problem more collective hours than your entire lifetime is unwarranted hubris.

The fact that ConcurrentTreeMap doesn't exist in java.util.concurrent should be ringing loud warning bells.

It's not like you have a choice. Thread safety doesn't compose. A function that only uses thread-safe constructs may not itself be thread safe. This means that using concurrent data structures isn't any sort of guarantee, and doesn't save you from having to think about concurrency. It will prevent you from running into certain kinds of bugs, and that may be valuable, but you'll still have to do your own work on top.

If you're doing that anyway, it tends to be easier and more reliable to forget about thread safety at the bottom, and instead design your program so that thread safety happens in larger blocks, and you have big chunks of code that are effectively single-threaded and don't have to worry about it.

The GP comment is not about designing your own concurrency data structures. It’s about the fact that if your higher-level logic doesn’t take concurrency into account, using the concurrent collections as such will not save you from concurrency bugs. A simple example is when you have two collections whose contents need to be consistent with each other. Or if you have a check-and-modify operation that isn’t covered by the existing collection methods. Then access to them still has to be synchronized externally.

The concurrent collections are great, but they don’t save you from thinking about concurrent accesses and data consistency at a higher level, and managing concurrent operations externally as necessary.

The people behind the concurrent containers in java.util.concurrent are smart, but they are limited by the fact that they are working on a necessarily lower-level API. As an application programmer, you can easily switch the high-level architecture so as not to require any concurrent containers. Perhaps you have sharded your data beforehand. Perhaps you use something like map-reduce architecture where the map step is parallel and require no shared state.
Once they expose data structures that allow generic uses like "if size<5, add item" I'll take another look. Until then, their definition of thread-safety isn't quite the same as mine.
You can take a look at Haskell's Software Transactional Memory then. Or you can take a look at something like the Linux kernel's Read-Copy-Update (RCU) abstraction, add some persistent data structures and a retry loop on top. It's indeed a very programmer friendly way of doing concurrency.
You're right. That would have been a better choice.