>>分享Java编程技术,对《Java面向对象编程》等书籍提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 33098 个阅读者 刷新本主题
 * 贴子主题:  《Java面向对象编程》第二版P448源代码有一个BUG 回复文章 点赞(0)  收藏  
作者:apolo    发表时间:2019-07-01 22:20:42     消息  查看  搜索  好友  邮件  复制  引用

在P448页讲解Condition条件接口中,书上给了一个例子为SyncTest.java.
定义了三个类:
Stack类:getPoint()、pop()和push()均利用外部锁进行了同步
Producter类:在run()方法中利用外部锁对Stack对象进行了同步
Consumer类:在run()方法中并没有对Stack对象进行同步,其具体实现为:
public void run(){
    String goods;
    for(int i = 0; i < 200; ++i){
        goods = theStack.pop();  //此处pop利用外部锁实现了同步,不会有问题
        System.out.println(getName()+".pop"+goods+"from"+theStack.getName());    //BUG出现在这一句
        yield();
    }
}
由于输出数据并不在同步代码块中,因此导致整个程序的输出结果为:
点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小
注意,这里程序的执行逻辑并没错,但是输出却出现了错误,因为在执行语句
goods = theStack.pop()将good9取出后,producter2获得了CPU的执行权,执行了push方法,放入了good9,并输出了
producter2 push 9
而后consumer1执行了输出语句:
consumer1 pop 9 (System.out.println(getName()+".pop"+goods+"from"+theStack.getName());)
以上原因造成了逻辑正确,而输出错误,因此应该把pop的输出数据放入pop中,这样不会出现这个输出错误了。



程序猿的技术大观园:www.javathinker.net
  Java面向对象编程-->内部类
  JavaWeb开发-->面向对象开发方法概述之UML语言(下)
  JSP与Hibernate开发-->使用Session(Ⅱ)
  Java网络编程-->Web运作原理(Ⅰ)
  精通Spring-->Spring、JPA与Hibernate的整合
  Vue3开发-->数据库事务的并发问题的解决方案
  解决javac编译错误: 编码UTF8/GBK的不可映射字符
  Java内存设置详解(含内存溢出问题的解决)
  Java并发编程的总结与思考
  十分钟带你搞懂 Java AQS 核心设计与实现!
  使用 RocketMQ 事务消息,实现分布事务
  Java异常堆栈信息以字符串形式输出
  分布式锁的原理和实现
  如何优雅地打印一个Java对象?
  用BigDecimal进行精确运算的范例
  Java入门实用代码:获取远程文件大小
  Java入门实用代码:修改链表LinkedList
  Java入门实用代码:获取数组长度
  Java程序初始化顺序(一看就懂)
  关于Java中try finally return语句的执行顺序浅析
  Java线程实现龟兔赛跑
  更多...
 IPIP: 已设置保密
楼主      
该用户目前不在线 apolo 
  
威望: 0
级别: 新手上路
魅力: 135
经验: 135
现金: 1058
发文章数: 6
注册时间: 0001-01-01
 消息  查看  搜索  好友  邮件  复制  引用


图片的内容为:
.
.
.
producter1 push good8
producter1 push good9
producter2 push good9
consumer1:pop good9
producter2 push good10
.
.
.
发文章时间 2019-07-01 22:21:40
 IPIP: 已设置保密 1 楼     
该用户目前不在线 sunweiqin 
  

威望: 0
级别: 高级天王 [荣誉]
魅力: 480
经验: 480
现金: 1128
发文章数: 171
注册时间: 2016-09-12
 消息  查看  搜索  好友  邮件  复制  引用


To apolo,非常赞叹你认真专研的学习态度。
你的建议非常正确,应该把Consumer类的打印语句也放到同步代码块中。这样,输出结果看起来才会符合逻辑。
发文章时间 2019-07-02 12:11:09
 IPIP: 已设置保密 2 楼     
1页 2条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。