我遇到的多线程的面试题

lliiqiang 2014-03-04 10:10:43
有1个全局变量
int sum=0
运行2个线程,代码如下
for(int i=1;i<=50;i++)
sum=sum+1;
问2个线程都运行完之后,sum的取值范围。
...全文
2797 42 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
42 条回复
切换为时间正序
请发表友善的回复…
发表回复
LangHua888 2014-12-21
  • 打赏
  • 举报
回复
sum = sum + 1 这个操作不是原子操作,这个加+1未必能够执行成功,所以取值范围是0-100
w382572397 2014-11-03
  • 打赏
  • 举报
回复
0-100 调用start并不一定线程就执行了.
sweetchild1985 2014-03-07
  • 打赏
  • 举报
回复
17楼分析的很到位
jsshizhanab 2014-03-06
  • 打赏
  • 举报
回复
51到101
java805 2014-03-06
  • 打赏
  • 举报
回复
public class Test { /** * @param args */ public static void main(String[] args) { Test2 a=new Test2(); Thread t1=new Thread(a); Test2 b=new Test2(); Thread t2=new Thread(b); t1.start(); t2.start(); } } class Test2 implements Runnable{ public static int sum = 0; public void run() { // TODO Auto-generated method stub for(int i=1;i<=50;i++){ try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } sum=sum+1; } System.out.println(sum); } } 经过代码测试结果应该是100-200
lyx266 2014-03-05
  • 打赏
  • 举报
回复
17楼说的很有道理 应该是2-100
sichuanwww 2014-03-05
  • 打赏
  • 举报
回复
DuanKong86 2014-03-05
  • 打赏
  • 举报
回复
引用 35 楼 lliiqiang 的回复:
[quote=引用 30 楼 DuanKong86 的回复:] 对于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两个过程[/quote] 恩, 的确, 反编译带thread的code时, 取值与赋值是分开的操作. 看来应该是局部变量与Thread里操作全局变量的不同导致的
       7: getfield      #14                 // Field sum:I
      10: iconst_1
      11: iadd
      12: putfield      #14                 // Field sum:I
lliiqiang 2014-03-05
  • 打赏
  • 举报
回复
其实就是两个线程相互并发覆盖对方的运行结果.
lliiqiang 2014-03-05
  • 打赏
  • 举报
回复
引用 30 楼 DuanKong86 的回复:
对于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两个过程
lliiqiang 2014-03-05
  • 打赏
  • 举报
回复
引用 23 楼 leilei0932_java 的回复:
[quote=引用 19 楼 ldh911 的回复:] [quote=引用 16 楼 lliiqiang 的回复:] 首先让第一个线程取得sum=0,然后让第二个线程循环49次.接着用第一个线程运行到1-50之间的值,然后第二个线程取得这个值,接着第一个线程运行完,第二个线程在这个值的基础之上加1,于是就可以得到2-51之间的值.这个需要6次配合。
看了一遍,觉得还是挺有道理的。[/quote] 仔细看了你的代码,其中有些存在异议的地方,探讨一下: 其中int value=sum;这种写法相当于定义了一个临时变量保存了sum等于0时的状态,当线程2循环49次后可以从value这个临时变量中取得0; 而题目中代码sum=sum+1;的这种写法,当线程2循环49次后其中标红的sum还有没有可能是0呢? [/quote] 线程取sum值其实是临时地将值放在内存中,但是没有改变sum的值,这个和局部变量存储差不多,只是把过程分解容易控制而已,局部变量是线程内部的,完全模拟封装了虚拟机的栈.
whos2002110 2014-03-04
  • 打赏
  • 举报
回复
50-100
lfcsunny 2014-03-04
  • 打赏
  • 举报
回复
哦,没看清,那就是100了
lliiqiang 2014-03-04
  • 打赏
  • 举报
回复
引用 8 楼 lfcsunny 的回复:
public class Threads implements Runnable {
	public int sum = 0;
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Threads ts = new Threads();
		Thread t1 = new Thread(ts);
		Thread t2 = new Thread(ts);
		t1.start();
		t2.start();
		try {
			Thread.sleep(5000);//保证两个线程都执行完
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(ts.sum);
	}

	public void run() {
		for (int i = 1; i <= 50; i++) {
			sum=sum+i;
		}
	}

}
sum=2550
完全错误,题目说的是sum=sum+1,而且你sum不是共用的.
明天的奇迹 2014-03-04
  • 打赏
  • 举报
回复
50-101 (执行次数 ,执行次数*线程数+(线程数-1) )
lfcsunny 2014-03-04
  • 打赏
  • 举报
回复
如果没有说两个线程都运行完的话,还有的说取值范围
lfcsunny 2014-03-04
  • 打赏
  • 举报
回复
public class Threads implements Runnable {
	public int sum = 0;
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Threads ts = new Threads();
		Thread t1 = new Thread(ts);
		Thread t2 = new Thread(ts);
		t1.start();
		t2.start();
		try {
			Thread.sleep(5000);//保证两个线程都执行完
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(ts.sum);
	}

	public void run() {
		for (int i = 1; i <= 50; i++) {
			sum=sum+i;
		}
	}

}
sum=2550
oh_Maxy 2014-03-04
  • 打赏
  • 举报
回复
引用 5 楼 ygycomon 的回复:
[quote=引用 3 楼 oh_Maxy 的回复:] 1到100 不过以现在机器的速度,1的概率应该很高很高。
版主你秀逗了吧。。从1加到50,不是50+50.。 最大值是2550[/quote] 同学,你再看看题?不是sum=sum+i哦~
oh_Maxy 2014-03-04
  • 打赏
  • 举报
回复
引用 4 楼 lliiqiang 的回复:
[quote=引用 3 楼 oh_Maxy 的回复:] 1到100 不过以现在机器的速度,1的概率应该很高很高。
请给出理由 我认为不可能等于1[/quote] 刚才试了下,确实不为1。要不你说说你的见解吧
致知Fighting 2014-03-04
  • 打赏
  • 举报
回复
引用 3 楼 oh_Maxy 的回复:
1到100 不过以现在机器的速度,1的概率应该很高很高。
版主你秀逗了吧。。从1加到50,不是50+50.。 最大值是2550
加载更多回复(20)

62,635

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧