本文共 674 字,大约阅读时间需要 2 分钟。
本节书摘来自异步社区《代码整洁之道》一书中的第13章13.2节挑战,作者【美】Robert C. Martin,更多章节内容可以访问云栖社区“异步社区”公众号查看。
13.2 挑战
并发编程为何如此之难?来看看下面这个小型类:public class X { private int lastIdUsed; public int getNextId() { return ++lastIdUsed; }}
比如,创建x的一个实体,将lastIdUsed设置为42,在两个线程中共享这个实体。假设这两个线程都调用getNextId( )方法,结果可能有三种输出:
线程一得到值43,线程二得到值44,lastIdUsed为44;
线程一得到值44,线程二得到值43,lastIdUsed为44;线程一得到值43,线程二得到值43,lastIdUsed为43。第三种结果令人惊异[3],当两个线程相互影响时就会出现这种情况。这是因为线程在执行那行Java代码时有许多可能路径可行,有些路径会产生错误的结果。有多少种不同路径呢?要真正回答这个问题,需要理解Just-In-Time编译器如何对待生成的字节码,还要理解Java内存模型认为什么东西具有原子性。简答一下,就生成的字节码而言,对于在getNextId方法中执行的那两个线程,有12870种不同的可能执行路径[4]。如果lastIdUsed的类型从int变为long,则可能路径的数量将增至2704156种。当然,多数路径都得到正确结果。问题是其中一些不能得到正确结果。
转载地址:http://gixwm.baihongyu.com/