学习《java多线程编程核心技术》遇到的一些问题
2018-04-10 00:00
429 查看
摘要: 这两天在看《java多线程编程核心技术》,按照示例代码执行的结果总是和书上的对不上,经过多番分析得出:示例代码是得不到书上的结果的。
首先先贴出示例代码:
ThreadA:
ThreadB:
Test:
以上代码主要是用来演示sleep() 加 while(true) 实现线程间通讯的示例代码,书中给出的示例结果是这样的:
然而我的执行结果总是这样的:
并且程序没有退出。这说明while(true)是执行的,但是符合进入list.size()==5的条件。
其实一开始我就认为示例代码是得不出示例的结果的,因为此书第二章节最后讲的是volatile关键字,说的是如何在变量线程间可见。theadA,threadB 中的list应该是线程私有栈中的变量,当时我就觉得声明MyList的时候要加volatile关键字才能得到示例结果,而且加了确实可以得到示例中的结果。但是我是个不太自信人,总觉的自己是不是哪里写错了,于是在while和if之间加了个sysout 打印看看list.size(),结果它居然进了if条件~~~我日~什么鬼,然后我有注释掉这行打印,它又没有进if条件。。。。
经过百般思过我想到了一个关键字synchronized 于是我点开System.out.Println()源码
同步关键字可以间接保证线程间变量可见性。
首先先贴出示例代码:
ThreadA:
public class ThreadA extends Thread { private MyList list; public ThreadA(MyList list) { super(); this.list = list; } @Override public void run() { try { for (int i=0;i<10;i++) { list.add(); System.out.println("添加了"+(i+1)+"个元素"); Thread.sleep(1000); } } catch (InterruptedException e) { e.printStackTrace(); } } }
ThreadB:
public class ThreadB extends Thread { private MyList list; public ThreadB(MyList list) { super(); this.list = list; } @Override public void run() { try { while (true) { if(list.size()==5) { System.out.println("==5 了 线程 b 要退出了"); throw new InterruptedException(); } } } catch (InterruptedException e) { e.printStackTrace(); } } }
Test:
public class Test { public static void main(String[] args) { MyList service = new MyList(); ThreadA a = new ThreadA(service); a.setName("A"); a.start(); ThreadB b = new ThreadB(service); b.setName("B"); b.start(); } }
以上代码主要是用来演示sleep() 加 while(true) 实现线程间通讯的示例代码,书中给出的示例结果是这样的:
添加了1个元素 添加了2个元素 添加了3个元素 添加了4个元素 添加了5个元素 ==5 了 theadB 要退出了 java.lang.InterruptedException at com.asiainfo.mcss.sm.thread.ThreadB.run(ThreadB.java:20) 添加了6个元素 添加了7个元素 添加了8个元素 添加了9个元素 添加了10个元素
然而我的执行结果总是这样的:
添加了1个元素 添加了2个元素 添加了3个元素 添加了4个元素 添加了5个元素 添加了6个元素 添加了7个元素 添加了8个元素 添加了9个元素 添加了10个元素
并且程序没有退出。这说明while(true)是执行的,但是符合进入list.size()==5的条件。
其实一开始我就认为示例代码是得不出示例的结果的,因为此书第二章节最后讲的是volatile关键字,说的是如何在变量线程间可见。theadA,threadB 中的list应该是线程私有栈中的变量,当时我就觉得声明MyList的时候要加volatile关键字才能得到示例结果,而且加了确实可以得到示例中的结果。但是我是个不太自信人,总觉的自己是不是哪里写错了,于是在while和if之间加了个sysout 打印看看list.size(),结果它居然进了if条件~~~我日~什么鬼,然后我有注释掉这行打印,它又没有进if条件。。。。
经过百般思过我想到了一个关键字synchronized 于是我点开System.out.Println()源码
/** * Prints a String and then terminate the line. This method behaves as * though it invokes <code>{@link #print(String)}</code> and then * <code>{@link #println()}</code>. * * @param x The <code>String</code> to be printed. */ public void println(String x) { synchronized (this) { print(x) 7fe8 ; newLine(); } }
同步关键字可以间接保证线程间变量可见性。
相关文章推荐
- 《Java多线程编程核心技术》学习笔记-第一章
- 关于学习编程中会遇到的一些小问题
- 在用SWT进行socket编程中遇到的一些问题的总结
- 在基于 Java 语言的编程中我们经常遇到的一些问题
- C++ 编程遇到的一些问题
- 通过plsql 测试存储过程遇到的问题和学习到的一些基础知识整理
- 2009-03-25技术学习:使用Wicket框架时遇到的问题
- 学习使用solr时遇到的一些问题,记录
- grails 学习过程中遇到的一些问题
- 学习驱动编程准备阶段遇到的几个问题
- 网络编程遇到的一些问题及答案
- 学习JAVA一个月来,所遇到的一些问题(不全)
- 学习钩子(Hook)过程中遇到的一些问题
- 【XEN学习笔记】XEN 4.1.0 PVOPS设置和启动中遇到的一些问题
- ISA的学习体会二:我做ISA服务器遇到的一些问题
- 在学习SSH中遇到的一些问题与大家共享
- 面试遇到的一些技术问题
- 11.29编程中遇到的一些问题以及解决办法
- 计算机科学与技术学习心得之计算机理论的一个核心问题--续谈其他的一些计算数学(转载)
- 09.12.13 linux/unix编程学习途径 关于个人技术发展的一些考量