38

GitHub - oldratlee/fucking-java-concurrency: 🎏 Simple show cases of java concurr...

 4 years ago
source link: https://github.com/oldratlee/fucking-java-concurrency
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

README.md

fucking-java-concurrency

👉 通过Demo演示出Java中并发问题。

🍎 整理Demo的原因

  • 可以观察到的实际现象 🙈 比 说说的并发原则 🙊 更直观更可信。
  • Java语言标准库支持线程,语言本身(如GC)以及应用(服务器端The Server side)中会重度使用多线程。
  • 并发程度设计在分析和实现中,复杂度大大增加。 如果不系统理解和充分分析并发逻辑,随意写代码,这样的程序用 『碰巧』 能运行出正确结果 来形容一点都不为过。

这里的Demo没有给出解释和讨论,并且都是入门级的 :neckbeard: ,更多了解请参见一些并发的问题讨论和资料

你在开发中碰到的并发问题的例子,欢迎提供(提交Issue)和分享(Fork后提交代码)! 😘


dining-philosophers-problem.jpg


🍺 无同步的修改在另一个线程中会读不到

Demo类com.oldratlee.fucking.concurrency.NoPublishDemo

Demo说明

主线程中设置属性stoptrue,以控制在main启动的任务线程退出。

问题说明

在主线程属性stoptrue后,但任务线程持续运行,即任务线程中一直没有读到新值。

快速运行

mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.NoPublishDemo

🍺HashMap的死循环

这个问题在疫苗:Java HashMap的死循环等多个地方都有讲解。
Demo类com.oldratlee.fucking.concurrency.HashMapHangDemo,可以复现这个问题。

Demo说明

主线程中开启2个任务线程执行HashMapput操作。主线程做get操作。

问题说明

通过没有持续的输出判定主线程Block,即HashMap的出现死循环。

快速运行

mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.HashMapHangDemo

🍺 组合状态读到无效组合

程序设计时,会需要多个状态记录(状态可以是个POJO对象或是int等等)。常看到多状态读写没有同步的代码,并且写的同学会很自然地就忽略了线程安全的问题。

无效组合 是指 从来没有设置过的组合。

Demo说明

主线程修改多个状态,为了方便检查,每次写入有个固定的关系:第2个状态是第1个状态值的2倍。在任务线程中读取多个状态。
Demo类com.oldratlee.fucking.concurrency.InvalidCombinationStateDemo

问题说明

任务线程中读到了 第2个状态不是第1个状态值2倍的值,即是无效值。

快速运行

mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.InvalidCombinationStateDemo

🍺long变量读到无效值

无效值 是指 从来没有设置过的值。

long变量读写不是原子的,会分为2次4字节操作。
Demo类com.oldratlee.fucking.concurrency.InvalidLongDemo

Demo说明

主线程修改long变量,为了方便检查,每次写入的long值的高4字节和低4字节是一样的。在任务线程中读取long变量。

问题说明

任务线程中读到了高4字节和低4字节不一样的long变量,即是无效值。

快速运行

mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.InvalidLongDemo

🍺 无同步的并发计数结果不对

Demo类com.oldratlee.fucking.concurrency.WrongCounterDemo

Demo说明

主线程中开启2个任务线程执行并发递增计数。主线程最终结果检查。

问题说明

计数值不对。

快速运行

mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.WrongCounterDemo

🍺 在易变域上的同步

常看到在易变域上的同步代码,并且写的同学会很自然觉得这样是安全和正确的。
# 问题分析见文章链接:在易变域上的同步,对应的英文文章:Synchronization on mutable fields
Demo类com.oldratlee.fucking.concurrency.SynchronizationOnMutableFieldDemo

Demo说明

主线程中开启2个任务线程执行addListener。主线程最终结果检查。

问题说明

最终Listener的个数不对。

快速运行

mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.SynchronizationOnMutableFieldDemo

🍺 对称锁死锁

# 问题分析见文章链接:对称锁死锁,对应的英文文章:Synchronization on mutable fields
Demo类com.oldratlee.fucking.concurrency.SymmetricLockDeadlockDemo

Demo说明

主线程中开启2个任务线程执行。

问题说明

任务线程死锁。

快速运行

mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.SymmetricLockDeadlockDemo

一些并发的问题讨论和资料

要深入了解请参见并发方面的系统的资料


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK