《Java并发编程的艺术》勘误和支持

本书源码下载地址

第一版第一次印刷勘误

第2页,thread.join();这句代码和上面一行代码交换位置。
第3页,第一个表格“并发比串行快多少”的第五行,慢=>差不多。
第9页,表2-1第三行缓存行。第一个缓存=》CPU高速缓存,缓存线=》缓存行,
第9页,表2-1第三行缓存行。需要使用多个主内存读周期=》现代CPU需要执行几百次CPU指令
第18页,代码少了第一行 public class Counter {

第一版第二次印刷勘误

第一版第三次印刷勘误

第一版第四次印刷勘误

  • 第168页LinkedBlockingQueue 有界阻塞队列 修改成 无界阻塞队列。
  • 第5页的源码,DeadLockDemo里面 private static String A = “A”; 这一行的private拼写少了个e。
  • 第112页的源码,work.get(count)后面少了个分号;。
  • 第186页的源码,代码第2、3行,user应改为User。
  • 第210页的图,图10-2左上角的类应该是Runnable;图10-3中有2个create漏了字母e,1个execute漏了字母2(找晓明修改下)
  • Trackback 关闭
  • 评论 (52)
    • 夜阳
    • 2015/08/11 12:11上午

    18页代码少了第一行public class Counter {

    76页表3-9把表3-8复制了一遍,完全错误

    • 下雨不打伞
    • 2015/09/06 9:17上午

    第5页的源码,DeadLockDemo里面 private static String A = “A”; 这一行的private拼写少了个e

    • abyjun
    • 2015/09/13 9:01下午

    请问,37页的图中的读事物写的是读高32位,是不是应该改为读整个long型变量

    • yangcheng33
    • 2015/10/07 5:56下午

    210页,图10-2左上角的类应该是Runnable;图10-3中有2个create漏了字母e,1个execute漏了字母2
    186页,代码第2、3行,user应改为User

    • yangcheng33
    • 2015/10/08 1:40上午

    112页,代码倒数第12行,漏掉了分号

    • 爪云
    • 2015/12/28 9:55上午

    31页, 第五行, volaLile 拼写错误, 应该是volatile

    • wuxiaolinchn
    • 2016/01/17 10:44上午

    5页,1.2死锁代码,2个重写Runnable接口的run方法都写成了publicvoid,两个关键字之间缺少空格。

    • qiguan123
    • 2016/01/27 7:24下午

    164页最后一行,应该是“如果p的next节点是null”吧。

    • superheizai
    • 2016/02/01 12:06下午

    59页,第三章,3.6.5标题,“溢出”==》“逸出”
    69,第三种,3.8.2第一行,(instance=new Singleton();),实际上例子给的是(instance= new Instance():)

    • superheizai
    • 2016/02/02 9:38上午

    虽然么有回复,但是我要继续报错:)
    第五章,5.2.2中5.自定义同步组件-TwinsLock部分,关于资源数的描述部分,“status为2”应该是“state为2”。
    第六章, 6.1.3的2.初始化segmentShift和segmentMask,其中”segmentSHift最大值是16″,不是最大值,是最小值。

    • 魏 鹏
    • 2016/04/06 11:28上午

    第三页

    Content Switch –> Context Switch

      • yoxibaga
      • 2016/10/06 4:58下午

      魏老师,请教一个问题,第四章最后【基于线程池的简单Web服务器】的demo,server启动之后,URL如何写呢?basepath = ‘F:\\workspace’

    • xiaohaizi
    • 2016/04/27 8:51下午

    你好 ,第4.4.4小节,115页 代码中 out.flush() 应该在socket.getOutputStream().write(array,0,array.length);之前调用,
    否则,内容会先于报文头发送。

    • sirding
    • 2016/09/08 5:20下午

    338页
    “因为CyclicBarrier设置了拦截线程的数量是2,所以必须等代码中的第一个线程和线程A 都执行完之后,才会继续执行主线程,然后输出2,所以代码执行后的输出如下。”

    逻辑应该是A线程一定是先执行的,但第一个线程和主线程的执行顺序是不一定的。所以执行的结果应该3、2、1或是3、1、2

    • MindHacks
    • 2016/12/21 9:40下午

    您好,第12页,第5行,第8行的Synchronized拼写错误,被拼成了Synchonized

    • 16789Mauersu
    • 2017/01/12 5:09下午

    对P134页的TwinsLock的unlock方法存疑

    public boolean tryReleaseShared(int returnCount) {
    for(;;) {
    int current = getState();
    int newCount = current + returnCount;
    if(compareAndSetState(current, newCount)) {
    return ture;
    }
    }
    }
    unlock方法及调用方法,都没有对当前线程进行判断,判断其是否持有锁,我觉得应该加上这个判断,因为只有持有所得线程才能释放锁

      • 16789Mauersu
      • 2017/01/12 5:14下午

      而且误操作,会导致整个锁状态处于异常状态

        • 16789Mauersu
        • 2017/01/12 5:17下午

        同理P123的Mutex类

          • helloworld
          • 2017/02/13 9:45下午

          不好意思哇,以上言论全部有误,个人没法删除,麻烦管理员帮忙删除下,以防误导其他人,谢啦

    • yanhui
    • 2017/02/11 6:10下午

    刚看书到第3页,看过表1-1的表格后,有点不太懂。

    书上说当执行并发累加不超过百万时,速度要比串行要慢。

    为什么超过百万时,并行的速度要快近一倍呢?是不是CPU的双核同时运行的结果。如果在单核CPU上,分时调度的结果一定是慢的啊。

    请各位大神给予解答,谢谢。

    • helloworld
    • 2017/02/15 4:42下午

    文字错误
    P147
    表5-12
    对比项列“当前线程释放锁并进入等待状态,在等待状态中不响应中断”疑似错误
    应该为“当前线程释放锁并进入等待状态,在等待状态中响应中断”

      • helloworld
      • 2017/02/15 4:43下午

      多了个“不”字

        • helloworld
        • 2017/02/15 4:51下午

        不好意思哇,以上言论再次全部有误,个人没法删除,麻烦管理员帮忙删除下,以防误导其他人,谢啦 🙁

    • style920
    • 2017/03/03 3:51下午

    版次: 2016年10月份第一版第六次印刷
    第七章 java中的13个原子操作类
    只有12个,在7.2原子更新数据AtomicIntegerArray重复

    • 猪会飞
    • 2017/03/05 7:53下午

    表1-1测试结果中:循环次数为10万次的这行,并发比串行快多少的结果应该是“快”吧???

    • zlsf
    • 2017/03/23 10:38下午

    您好,正在拜读该书。43页给予保守策略的…..屏障插入策略。下面4点,最后两条有2个volatile读操作后,的规则。是不是应该有一个是读前,一个是读后

      • zlsf
      • 2017/03/23 10:44下午

      是我理解错误,没看到下面的内容,请忽略这个反馈。抱歉

    • lt199025
    • 2017/05/28 11:41上午

    你好,目前正在拜读该书,发现一个问题
    版次:2016年4月第1版第5次印刷
    描述:第2章,第10页的第7行,提到8.1.4节,但我没在该书中找到相应的的章节,不知是不是印刷的问题,如果是,那么应该是哪个章节

    • wkzq
    • 2017/09/24 10:05上午

    第一版第一次印刷
    146页第四行“RentrantReadWriteLock”少了个e

    • sanshiz
    • 2017/11/08 11:09下午

    01,案例代码太简单,排版不好
    02,注释有很多欠缺,并且注释有的地方很晦涩

    • sanshiz
    • 2017/11/09 1:14上午

    ScheduledThreadPoolExecutor, ThreadPoolExecutor, 作者你確定都有submit()方法,10章裏面很多地方這樣寫,比如p212

    • bingqiang.lin
    • 2018/02/05 5:50下午

    您好,版次:2017年7月第1版第9次印刷,P134,TwinsLock中的tryAcquireShared(int reduceCount)方法,缺少返回语句。

    • like
    • 2018/05/03 6:44下午

    版次:2017年7月第1版第9次印刷,P158,“segmentShift等于32减sshift,所以等于28。”和后边的“所以segmentShift最大值是16”前后矛盾

    • like
    • 2018/05/06 11:17上午

    P193,代码清单8-4的执行结果还有一种可能是3 2 1,只等线程A,并不等待第一个线程

    • yuanye3486
    • 2018/09/01 4:10下午

    P39,有部分内容让我感到疑惑,原书内容如下:

    简而言之,volatile变量自身具有下列特性。

    原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不
    具有原子性。

    在我的理解中 volatile 不是只能保证变量的可见性,不能保证其原子性吗?
    希望作者能帮助解答,非常谢谢!

    • stonej
    • 2019/04/25 2:54下午

    您好:正在拜读 并发编程的艺术

    关于第3章JMM中 3.1.4小节中的 表3.3 内存屏障类型表 有些不明白的地方

    1.关于4中类型的屏障 涉及到的 Load 指令是否是指从主存中读取更新线程自己的工作内存中

    2.Load1 LoadLoad Load2 屏障中的Load1 指的是一条load指令 还是屏障上面的涉及到的所有Load 指令

    3.Store1 StoreLoad Load2 屏障 书中描述会把屏障之前的store操作刷新到主存 那么是否也会把storeLoad屏障之前的Load 从主存中加载到工作线程中 。

    • eggo
    • 2019/05/16 10:02上午

    尊敬的作者:
    您好!我正在拜读您的《Java并发编程的艺术》,第四章的4.2.3 理解中断一节,Interrupted程序的执行结果与书中的并不一致,SleepThread程序的打印结果为:SleepThread interrupted is true。不知是否是在java12.0.1版本对InterrupedException抛出之前清除中断标志位的机制修改了,还请在您有时间的时候解答以下。

    • eggo
    • 2019/05/18 5:07下午

    尊敬的作者:
    您好!我正在拜读您的《Java并发编程的艺术》,正如您在4.1.5 Daemon线程一节所说的,不能把执行关闭或者清理资源的逻辑放到Daemon线程的finally块中。
    然而,在第5章第5节——自定义同步组件,在程序TwinsLockTest.java程序中,在Worker的finally块中使用了lock.unlock();语句,这样做的理由是什么呢?

    • Jasonrale
    • 2019/07/21 5:59下午

    作者您好,我正在读这本书,我发现第52页,也就是3.5.3节,其中ReentrantLock的unlock()方法的调用轨迹顺序写错了,应该先Sync:release(int arg),然后AQS:tryRelease(int releases)。

      • 842036133@qq.com
      • 2019/07/31 3:54下午

      你好,我刚也在看这节,我看的JDK8的源码,作者写的我觉得没有错,因为Sync抽象类是继承AQS的,所以作者说先调用AQS的方法应该也可,在调用链的最后,调用了ReentrantLock的静态内部类sync的方法tryRelease,因为静态内部类Sync继承AQS,重写了tryRelease方法,所以最后调用的是Sync的tryRelease方法

        • 842036133@qq.com
        • 2019/08/19 1:33下午

        题主我重新整理下ReentrantLock的unlock()方法的调用链,觉得和书上写的吻合,unlock方法调用其静态内部类Sync的release()方法,此方法没有重写,实际是调用AQS的release方法,之后在AQS的release方法内调用了ReentrantLock的静态内部类Sync重写的tryRelease方法,所以顺序是1.ReentrantLock.lock() 2.AQS.release() 3.Sync.tryRelease(),公平锁和非公平锁的调用链相同

    • webber
    • 2019/07/28 6:28下午

    volatile写前面加StoreStore内存屏障,可以禁止volatile前面的普通写和volatile变量重排序,但是普通读变量感觉是没有办法禁止重排序的?

      • 842036133@qq.com
      • 2019/07/31 3:57下午

      个人认为是volatile写后面加的storeload屏障保证了写之前的所有操作对之后的读操作可见(实现是禁止了写之前的所有操作重排序到写之后,包括普通读变量的操作)

    • cy503328434
    • 2019/08/06 1:56下午

    你好。2018年10月第一版第13次印刷,158页 2.初始化segmentShift和segmentMask 本段的倒数第二行。“所以segmentShift”最大值16 应该是最小值是16吧。

    • twx626
    • 2019/11/04 10:24上午

    作者,您好,请教个问题,书中85页到86页里的代码清单4-2 Priority.java中,Job.jobCount这个字段如何保证可见性的?

您必须 登陆 后才能发表评论

return top