有1个全局变量
int sum=0
运行2个线程,代码如下
for(int i=1;i<=50;i++)
sum=sum+1;
问2个线程都运行完之后,sum的取值范围。
------解决方案--------------------
1到100
不过以现在机器的速度,1的概率应该很高很高。
------解决方案--------------------
50-101
(执行次数 ,执行次数*线程数+(线程数-1) )
------解决方案--------------------
50-100
------解决方案--------------------
仔细看了你的代码,其中有些存在异议的地方,探讨一下:
其中int value=sum;这种写法相当于定义了一个临时变量保存了sum等于0时的状态,当线程2循环49次后可以从value这个临时变量中取得0;
而题目中代码sum=sum+1;的这种写法,当线程2循环49次后其中标红的sum还有没有可能是0呢?
------解决方案--------------------
理论取值范围是1到100,如果考虑线程并发量的话,貌似可以计算出概率范围。
------解决方案--------------------
对于17楼的答案我有个疑问:
这是Java:package com.test;
public class Test {
public static void main(String[] args) {
int sum = 0;
for(int i=0;i<10;i++) {
sum = sum+1;
}
System.out.println(sum);
}
}
这是对应的反汇编:D:\Code\WorkSpace_3.6\Test\bin\com\test>javap -c Test
Compiled from "Test.java"
public class com.test.Test extends java.lang.Object{
public com.test.Test();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iconst_0
3: istore_2
4: goto 13
7: iinc 1, 1
10: iinc 2, 1
13: iload_2
14: bipush 10
16: if_icmplt 7
19: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
22: iload_1
23: invokevirtual #22; //Method java/io/PrintStream.println:(I)V
26: return
}
可以从第7行看到, 对sum的+1操作,只用了一行,而在17楼的示意代码中,是先把sum的值取出来,然后运行线程2,再回过来用这个sum的值,所以对于这处,我还有一点疑问: 示意代码会不会破坏了原题的代码语义呢?
能够猜到这个功能不是一个操作,要是一个整体结果肯定是100.
你也可以写成int value=sum+1,sum=value;
sum=sum+1;关键是取sum和赋值sum两个过程
恩, 的确, 反编译带thread的code时, 取值与赋值是分开的操作.
看来应该是局部变量与Thread里操作全局变量的不同导致的
7: getfield #14 // Field sum:I
10: iconst_1
11: iadd
12: putfield #14 // Field sum:I
------解决方案--------------------
51到101