- Notifications
You must be signed in to change notification settings - Fork342
🎏 Simple showcases of java concurrency problems, seeing 🙈 is believing 🐵
License
oldratlee/fucking-java-concurrency
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
📖 English Documentation |📖 中文文档
Simple showcases ofJava concurrency problems, seeing 🙈 is believing 🐵.
- The actual phenomenon that can be observed 🙈 is more intuitive and more trustworthy than the concurrency principle mentioned 🙊.
- The
Javalanguage standard library supports threads, multithreading is heavily used in the language itself (such asGC) and applications (the server side). - Concurrency program design, in the analysis and implementation, the complexity is greatly increased. If you do not fully understand and systematically analyze the concurrent logic, and write code at will, it is not an exaggeration to describe such a program as "accidentally" running with the correct result.
- The demos here do not give explanations and discussions, and they are all entry-level
. For more information, please loop up the concurrency materials by yourself.
- The demos here do not give explanations and discussions, and they are all entry-level
Examples of concurrency problems you encountered in development are welcome to provide (submit Issue) or share (pull request after Fork)! 😘
- 🍺 Update without synchronization cannot be read in another thread
- 🍺 Infinite loop of
HashMap - 🍺 Combined state read invalid combination
- 🍺
longvariable read invalid value - 🍺 the result of concurrency count without synchronization is wrong
- 🍺 Synchronization on mutable fields
- 🍺 Deadlock caused by the symmetric locks
- 🍺 Livelock caused by reentrant locks
- 🍺 Instruction reordering causes non-final field variable read error
- 🍺 Cyclic Thread Pool Deadlock
Demo classNoPublishDemo.
Set the fieldstop totrue in themain thread to control the exit of the task thread started inmain.
After themain thread fieldstop istrue, the task thread continues to run, that is, no new value has been read in the task thread.
./mvnw compile exec:java -Dexec.mainClass=fucking.concurrency.demo.NoPublishDemo
This problem has been explained in many places.
The Demo classHashMapHangDemo can reproduce this problem.
Two task threads are opened in the main thread to perform the put operation ofHashMap. The main thread does the get operation.
The main thread Block is determined by no continuous output, that is, the endless loop ofHashMap appears.
./mvnw compile exec:java -Dexec.mainClass=fucking.concurrency.demo.HashMapHangDemo
When programming, multiple state records will be required (state can be aPOJO object orints, etc.).
It is often seen that the multi-state read and write code is not synchronized, and the person who write it will naturally ignore the issue of thread safety.
Invalid combinations are combinations that have never been set.
The main thread modifies multiple states. For the convenience of checking, each write has a fixed relationship: the second state is twice the value of the first state. Read multiple states in a task thread.Demo classInvalidCombinationStateDemo.
The second state read in the task thread is not twice the value of the first state, that is, an invalid value.
./mvnw compile exec:java -Dexec.mainClass=fucking.concurrency.demo.InvalidCombinationStateDemo
An invalid value is a value that has never been set.
Reading and writing oflong variables is not atomic and will be divided into two 4-byte operations.
Demo classInvalidLongDemo.
The main thread modifies the long variable. For the convenience of checking, the upper 4 bytes and the lower 4 bytes of the long value written each time are the same. Read the long variable in the task thread.
In the task thread, a long variable whose upper 4 bytes and lower 4 bytes are different is read, which is an invalid value.
./mvnw compile exec:java -Dexec.mainClass=fucking.concurrency.demo.InvalidLongDemo
Demo classWrongCounterDemo.
Two task threads are opened in the main thread to execute concurrent incrementing counts. Main thread final result check.
The count value is incorrect.
./mvnw compile exec:java -Dexec.mainClass=fucking.concurrency.demo.WrongCounterDemo
It is common to see synchronization code on a volatile field, and the person who write it will naturally feel that this is safe and correct.
# For problem analysis, see the articleSynchronization on mutable fields.
Demo classSynchronizationOnMutableFieldDemo.
Two task threads are opened in the main thread to executeaddListener. Main thread final result check.
The final count of Listeners is incorrect.
./mvnw compile exec:java -Dexec.mainClass=fucking.concurrency.demo.SynchronizationOnMutableFieldDemo
# For problem analysis, see the articleSynchronization on mutable fields
Demo classSymmetricLockDeadlockDemo.
Two task threads are opened in the main thread for execution.
Task thread deadlocked.
./mvnw compile exec:java -Dexec.mainClass=fucking.concurrency.demo.SymmetricLockDeadlockDemo
# For a problem description, see the paragraph about livelocksin this article
Demo classReentrantLockLivelockDemo.
Two task threads are trying to acquire a lock that the other thread holds while holding their own lock.
While the threads are releasing their own lock constantly, they are also re-locking it immediately, denying the other threada chance to acquire both locks. Since both threads are not blocked from executing but blocked from doing meaningful work,this is a livelock.
./mvnw compile exec:java -Dexec.mainClass=fucking.concurrency.demo.ReentrantLockLivelockDemo
Demo classFinalInitialDemo.
The writer thread calls the constructor of the class, and the reader thread obtains the member variables of the non-final domain of the class.
When calling the constructor, instruction reordering may occur, placing non-final domain variables outside the constructor,causing the writer and reader threads to obtain the default initial values of the variables.(Instruction ordering does not necessarily occurand requires specific hardware and JVM environments).
./mvnw compile exec:java -Dexec.mainClass=fucking.concurrency.demo.FinalInitialDemo
Demo classCyclicThreadPoolDeadLockDemo.
This example demonstrates the issue of deadlock caused by cyclic dependencies between tasks when using thread pools,and how to avoid this situation usingCompletableFuture.
In thebadCase, two thread pools,pool1 andpool2, submit tasks to each other, forming a cyclic dependency.When the thread pool's threads are exhausted, all executing tasks wait for other tasks to complete, leading to a deadlock.ThegoodCase resolves the deadlock issue by using asynchronous chained calls withCompletableFuture, thus avoiding thread pool blocking.
./mvnw compile exec:java -Dexec.mainClass=fucking.concurrency.demo.CyclicThreadPoolDeadLockDemo
About
🎏 Simple showcases of java concurrency problems, seeing 🙈 is believing 🐵
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.
Contributors5
Uh oh!
There was an error while loading.Please reload this page.
