黑马程序员技术交流社区
标题:
关于同步问题
[打印本页]
作者:
李云锋
时间:
2014-4-10 11:15
标题:
关于同步问题
class ThreadDemo4
{
public static void main(String[] args)
{
Consumer c=new Consumer();
Thread t1=new Thread(c);
Thread t2=new Thread(c);
t1.start();
t2.start();
}
}
//定义一个银行类
class Bank
{
private int sum;
Object obj=new Object();
public void add(int num){
sum+=num;
System.out.println("sum="+num+"..."+Thread.currentThread().getName());
}
}
//定义一个客户类
class Consumer implements Runnable
{
private Bank bank=new Bank();
public void run(){
for(int i=0;i<3;i++){
bank.add(100); //一次存100,循环3次
}
}
}
这个是毕老师讲课的一个小程序:2个人去银行存钱,总共存3次一次存一百,然后打印出银行的总金额
这个程序不安全性的问题是add方法内,如果先执行sum+=num这句话,然后被别的线程抢去执行,就会发生错误(有时候同时输出两个200,但为什么不同时输出两个300或者其他呢),我现在把add内方法改写成System.out.println("sum="+(sum+=num)+"..."+Thread.currentThread().getName());,去掉上面这句,为什么还会出现这种问题?
作者:
fufeng
时间:
2014-4-10 21:29
也是可能出现300或者是其他的的,因为cpu在执行的时候是不停的在进程中进行切换的,比如当
sum+=num;
//线程1第二次执行到这里,此时线程2第一次/执行到这里,则num的值就变为了300,然后线程1和线程2执行打印语句就会出现两个300了。当然这具有一定的随机性,因为线程1和线程2获得cpu的执行权是不确定的 System.out.println("sum="+num+"..."+Thread.currentThread().getName());
复制代码
其实你将+=num写在里面和写在外面其实没什么大的区别,
因为sum是共享数据,所以要使用同步代码块
synchronized(Bank.class)
{
sum+=num;
System.out.println("sum="+num+"..."+Thread.currentThread().getName());
}
复制代码
让执行该代码时,只能有一个进程执行,执行完了才让其他进程来执行
作者:
李云锋
时间:
2014-4-11 11:20
fufeng 发表于 2014-4-10 21:29
也是可能出现300或者是其他的的,因为cpu在执行的时候是不停的在进程中进行切换的,比如当
其实你将+=num ...
谢谢您的见解
作者:
曹冬明
时间:
2014-4-14 09:56
理论上时可以出现的,400,,500都可能
作者:
xiaowei
时间:
2014-5-8 11:38
可能出现两个300
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2