4 ms·
The examples translate Go idioms directly to Java code rather than using Java idioms; you wouldn't normally write Java like Go any more than you'd write Go like
by pron 5y ago
The examples translate Go idioms directly to Java code rather than using Java idioms; you wouldn't normally write Java like Go any more than you'd write Go like Java.
They also make use of constructs that are overkill for such simple examples. For example, the first example could be written as:
Thread.startVirtualThread(() -> say("world"));
say("hello");
which would also replicate same concurrency bug as in the original Go program (the Java example, as written, does not have that bug, but neither would
var t = Thread.startVirtualThread(() -> say("world"));
say("hello");
t.join();
).
Go makes certain concurrency bugs easy to introduce and hard to find, while Java helps avoid them, but that is also not easy to see from these particular examples.
- emccue 5y agoYeah, sorry. I would have used .startVirtualThread more if I wasn't under the impression that I needed to do Thread.currentThread().interrupt() when catching and re-throwing as a RuntimeException. So I was choosing between the noise of that in the examples and the noise of the executor + submit with a lambda that returned null.
- dhab 5y agoAfter mulling between Elixir vs Go to have a tool in the toolbelt covering the use-case of concurrent server-side apps, I picked a book on Go and went through the first chapter. Disenchanted to hear (some) concurrency bugs easy to introduce and hard to find in Go. Could someone mention how does this compare to Elixir?
- xyproto 5y agoIt all depends on what you're trying to do. These cases work flawlessly in Go, in my experience: * Batch 10 tasks and run them concurrently (using WaitGroups). * Locking resources while reading and writing with a mutex like sync.RWMutex, using .Lock() and .Unlock(), often together with defer. * Locking resources while only reading with a sync.RWMutex, using .RLock() and .RUnlock(), often together with defer. * Running code "in the background" with goroutines, ie. go func() { <code goes here> }(). * Detecting race conditions by building with go build -race and then running the program. However, when using channels, select, closing channels, waiting on channels in a for loop etc, things can easily become more subtle. On a general basis, I disagree that concurrency bugs are easy to introduce and hard to find in Go. However, pure functional programming languages like Haskell, with little state, will always have the upper hand when it comes to concurrency. See also: https://gobyexample.com/waitgroups https://gobyexample.com/waitgroups https://gobyexample.com/mutexes https://gobyexample.com/mutexes https://gobyexample.com/defer https://gobyexample.com/defer https://gobyexample.com/goroutines https://gobyexample.com/goroutines https://gobyexample.com/non-blocking-channel-operations https://gobyexample.com/non-blocking-channel-operations
- kaba0 5y agoUnfortunately go’s defer statement is function scopes so it is very easy to not unlock a mutex at the intended place.
- cle 5y agoIs there an idiom in Loom for cancellation propagation and deadlines? I can't find anything in https://download.java.net/java/early_access/loom/docs/api/java.base/java/util/concurrent/Executors.html https://download.java.net/java/early_access/loom/docs/api/ja... about it. Do we need to run a second virtual thread that waits on the cancellation condition and interrupts, and then handle that exception gracefully in the interrupted virtual thread?