加法多线程

projoy 2011-06-03 11:17:03
加精
我有两个文件:AddThread.java进行加法操作。Core.java是主线程文件。得到的结果sum = 10. 可是我觉得应该得到20才对呀。
package Threads;

public class AddThread implements Runnable{
private volatile static int sum = 0;
public AddThread(){

}

public void run(){
{
for(int i = 0;i<10;++i){
int temp = sum;
temp = temp +1;
try{
Thread.sleep(20);
}catch(InterruptedException e){
System.out.println(e);
}
sum = temp;
System.out.println("This sum is "+ sum);
}
}
}

public static int getSum(){
return sum;
}
}


package Threads;

public class Core {
public static void main(String[] args){
AddThread first = new AddThread();
AddThread second = new AddThread();

Thread one = new Thread(first);
Thread two = new Thread(second);
one.setName("firstThread");
two.setName("secondThread");

one.start();
two.start();

while(one.isAlive()||two.isAlive()){

}

System.out.println(AddThread.getSum());

}

}


...全文
1258 60 打赏 收藏 转发到动态 举报
写回复
用AI写文章
60 条回复
切换为时间正序
请发表友善的回复…
发表回复
lxt8155396 2011-06-09
  • 打赏
  • 举报
回复
来学习了~~
zoeg 2011-06-09
  • 打赏
  • 举报
回复
这种情况,请使用AtomicInteger

final AtomicInteger sum=new AtomicInteger(0);
for(int i=0;i<2;i++)
new Thread(){
public void run(){
for(int i=0;i<10;++i){
try{
Thread.sleep(20);
}catch(InterruptedException e){
}
System.out.println("This sum is "+sum.addAndGet(1));
}
}
}.start();
  • 打赏
  • 举报
回复
的确是线程同步出了问题
Linroc 2011-06-09
  • 打赏
  • 举报
回复
学习一下。。。
jimiStephen 2011-06-09
  • 打赏
  • 举报
回复
学习了我刚学线程没有看出门道
Sandii77 2011-06-09
  • 打赏
  • 举报
回复
好好学习,天天向上
qiuwentianmingxin 2011-06-09
  • 打赏
  • 举报
回复
package Threads;

public class AddThread implements Runnable{
private volatile static int sum = 0;
public AddThread(){

}

public void run(){
{
for(int i = 0;i<10;++i){
int temp = sum;
temp = temp +1;
try{
Thread.sleep(20);
}catch(InterruptedException e){
System.out.println(e);
}
sum = temp;
System.out.println("This sum is "+ sum);
}
}
}

public static int getSum(){
return sum;
}
}

这个用来多线程也可以把在单线程的力面得
zoeg 2011-06-09
  • 打赏
  • 举报
回复
补充下:
使用int sum;sum++;
这种方法用来保证最后的累加和与实际累加次数相一致是足够的,但不能保证每次获取的数值相同
例如,线程中int now=sum++;就可能导致两个线程中获取到相同的值,虽然概率很低,但对某些场景足以致命!
AtomicInteger等相关的数值包装器可以非常方便地用来在多线程中的原子操作,典型的比如创建一个流水号是再方便不过了,不需要繁琐的使用同步关键字控制,也不要挖空心思寻找是否有漏洞!
juhuacha159 2011-06-08
  • 打赏
  • 举报
回复
学习一下
三心不可得 2011-06-07
  • 打赏
  • 举报
回复
1. volatile是用在sum上了,所以你单一的操作sum时不需要同步,但是你for循环里又让sum的值给了

temp,temp可不是volatile的,需要同步的。

2. 之所以是10是因为你在for循环中使用了Thread.sleep(20)这句话,first线程进来的时候temp =

temp + 1,但是紧接着first线程睡眠,这个时候还没来得及执行sum = temp,所以sum的值还是以前的

值,这个时候second线程进来,执行和first线程几乎同样的操作,所以会看到结果为10。要想变为20,把

Thread.sleep(20)去掉,或者synchronized.
XJAVASunjava 2011-06-07
  • 打赏
  • 举报
回复
既然有volatile在sum变量上使用,那么应该不会出现脏数据...那么为什么每次都是10?这个也想求高手解释下,同样不解..
春文秋武 2011-06-07
  • 打赏
  • 举报
回复

public class AddThread implements Runnable{
private static int sum=0;
public AddThread(){

}
private synchronized static void add(){
sum++;
}
public void run(){
for(int i = 0;i<10;++i){
add();
System.out.println("This sum is "+ sum);
}
}

public static int getSum(){
return sum;
}
}

http://blog.csdn.net/whuqin/archive/2011/06/03/6525475.aspx
卡卡西CC 2011-06-07
  • 打赏
  • 举报
回复
路过看看
liuxh109 2011-06-07
  • 打赏
  • 举报
回复
应该用synchronized对sum同步
宝印手 2011-06-07
  • 打赏
  • 举报
回复
学习了,呵呵
lihong729505755 2011-06-07
  • 打赏
  • 举报
回复
学习了
weston_cao 2011-06-07
  • 打赏
  • 举报
回复
看来楼主对于线程的运行还不是很了解啊,你看你的AddThread中的run()方法

int temp = sum;
temp = temp +1;
try{
Thread.sleep(20);
}catch(InterruptedException e){
System.out.println(e);
}
sum = temp;

你的temp是临时变量,sum是静态变量,你的第一个线程获取到sum值赋给temp,然后temp自增,这里是没有改变sum值的,然后第一个线程睡眠,这时第二个线程获取资源运行,同样的获取sum,这里的sum的值和第一个获取的是一样的,所以temp值也是一样的,相当于2个线程对sum赋同一个值,所以的程序运行的结果是
This sum is 1
This sum is 1
This sum is 2
This sum is 2
This sum is 3
This sum is 3
This sum is 4
This sum is 4
This sum is 5
This sum is 5
This sum is 6
This sum is 6
This sum is 7
This sum is 7
This sum is 8
This sum is 8
This sum is 9
This sum is 9
This sum is 10
This sum is 10
小王来巡山 2011-06-07
  • 打赏
  • 举报
回复
学习中,顶一个
suqizeng 2011-06-07
  • 打赏
  • 举报
回复
谢谢分享~~~~~~~~~~~
zlcp520 2011-06-06
  • 打赏
  • 举报
回复
内容存入剪贴板
加载更多回复(36)

62,623

社区成员

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

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