3 ms·
As an aside Java's concurrency is outright confusing and just plain hard to get right. Doing concurrency in golang was like a breath of fresh air.
by theflyinghorse 7y ago
As an aside Java's concurrency is outright confusing and just plain hard to get right. Doing concurrency in golang was like a breath of fresh air.
- apta 7y agoWhat's confusing about it? It's built on threads and mutexes, not unlike golang with its goroutines and mutexes. The main difference is that Java will be getting green threads soon, which will allow the user to spawn hundreds of thousands of them if he/she wants to.
- theflyinghorse 7y ago> What's confusing about it? Do I use Thread, Runnable, Executor, ExecutorService, or CompletableFutures? How do they interact with synchronized and Locks and which Locks do I use? Where do Semaphores fit in this picture? Sure, for someone who is in Java day in and day out and who deal with concurrent java all the time these might be very straightforward tools with clear separation of goals and intent. In my personal experience there are always easy to introduce bugs with Java's concurrency, and every time I have to do something concurrent in Java I reach for my notes first trying to refresh my memory on what's what, which I don't need to do with golang.
- apta 7y ago> Do I use Thread, Runnable, Executor, ExecutorService, or CompletableFutures It depends on what you need. Executor is an interface, so you can't use that directly, you have to use one of its implementations (like ExecutorService). CompletableFuture is what you use when you want to handle the return type of a given function or method call. I've come across so much golang code where a function that returns an error is invoked with "go foo()", and the error is ignored. The thing is, when you use golang, you have to re-write all these abstractions yourself anyway. Want to have a function execute in the background then you wait on the value? You have to pass in a channel and wait on it. What if it now returns an error? You have to pass in two channels now, or return a composite struct. In Java, you'd use a CompletableFuture and be done. Semaphores are similar to WaitGroup in golang (but with more use cases obviously). You get much more control, as well as writing code with a clear intent when you use its concurrency abstractions. In golang, you're writing much lower level code that you have to dig in to understand what's going on. Not to mention that in golang it's difficult to provide anything that comes close to what's in the java.util.concurrent package, mainly due to the lack of generics.