Java多线程Sample 1
来源:互联网 发布:Linux设置用户得密码 编辑:程序博客网 时间:2024/06/11 11:04
源码地址在github的ThreadsSafeProblem仓库demo1包。
一、问
内存中有一个整型变量value=0,两个线程都获取它后,将变量自加,会输出什么结果?
二、代码
UnsafeSequence.java
package demo1;public class UnsafeSequence { private int value; public int getNextVal(){ return value++; }}
MyRunnable.java
package demo1;public class MyRunnable implements Runnable { UnsafeSequence unsafeSequence; //向线程注入公用对象 public MyRunnable(UnsafeSequence unsafeSequence) { this.unsafeSequence = unsafeSequence; } @Override public void run() { System.out.println(Thread.currentThread().getName()+":"+unsafeSequence.getNextVal()); }}
Main.java
package demo1;public class Main { public static void main(String[] args) { //定义公用对象 UnsafeSequence unsafeSequence = new UnsafeSequence(); //定义两个线程 MyRunnable m1 = new MyRunnable(unsafeSequence); MyRunnable m2 = new MyRunnable(unsafeSequence); Thread t1 = new Thread(m1); Thread t2 = new Thread(m2); //启动线程 t1.start(); t2.start(); }}
三、选项
看完代码后,你觉得会输出什么呢?
- A. t1:0 和 t2:1
- B. t1:0 和 t2:0
- C. t1:1 和 t2:0
- D. t2:0 和 t1:1
- E. t2:0 和 t1:0
- F. t2:1 和 t1:0
答案:ABCDEF
四、分析原因
UnsafeSequence类中的value++操作,执行的过程中,大概可以分为取数、操作、写回3个操作,由于两个线程的这三个操作顺序的不确定性,所以上面程序输出的结果也有所不同。
如图这种状况,输出结果为t1:0 t2:0,至于其它情况可以多允许几次,估计就能看到不同的结果。
五、通过字节码分析
使用javap -v UnsafeSequence.class反编译查看字节码:
{ public demo1.UnsafeSequence(); flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #10 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 3: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Ldemo1/UnsafeSequence; public int getNextVal(); flags: ACC_PUBLIC Code: stack=4, locals=1, args_size=1 0: aload_0 1: dup 2: getfield #18 // Field value:I 5: dup_x1 6: iconst_1 7: iadd 8: putfield #18 // Field value:I 11: ireturn LineNumberTable: line 7: 0 LocalVariableTable: Start Length Slot Name Signature 0 12 0 this Ldemo1/UnsafeSequence;}
可以很清楚的看到,getNextVal方法做的0-11的操作,如果t1的putfield执行在t2的aload_0后,则t1/t2输出的结果都为0,否则一个为0一个为1。
0 0
- Java多线程Sample 1
- java 多线程用例sample
- 多线程sample。。
- java nio client sample
- java concurrent code sample
- CICS JAVA SAMPLE
- A sample Java App
- Java Thrift Server Sample
- Java in sample
- 多线程之使用互斥信号量Sample~
- 多线程之使用事件对象Sample。。
- 多线程之使用临界区Sample。。
- Sample Java ORB Protocol Sepcification
- JAVA UDP Server/Client Sample
- Events Sample Code(1)
- Excel VBA Sample 1
- Sample Application分析(1)
- 代码SAMPLE 1
- Hadoop基础教程-第3章 HDFS:分布式文件系统(3.3 HDFS参数解读)
- Redis多机数据库思维导图
- 过路费
- [YTU]_2354 (H 实现复数类中的加运算符重载【C++运算符重载】)
- ssh--service注入时出错:ERRORDefaultDispatcherErrorHandler:42
- Java多线程Sample 1
- 【Angular2】核心概念
- java水仙花数
- 结构体
- Mac下Chrome 多个 tab 间切换的快捷键
- 路由器入侵
- 联合分布 & 条件分布 & 边缘分布
- Memcached的使用与CAS命令
- Ubuntu 16.04 禁用guest账户,亲测可用