public class ThreadDemo {
public static void main(String[] args) {
new ThreadDemo().run();
}
public void run() {
Family f = new Family();
new Thread(f, "qizi").start();
new Thread(f, "zhangfu").start();
while (true) {
if (f.getTimes() >= 2) {
f.show();
break;
}
}
}
class Family implements Runnable {
private int saveMoney;
private int getMoney;
private int curMoney;// 当前取的钱
private int times = 0;
// 可以直接创建一个对象来作为同步锁的钥匙
Object key = new Object();
public Family() {
saveMoney = 10000;
getMoney = 2000;
curMoney = 0;
}
public int getTimes() {
return times;
}
@Override
public void run() {
// TODO Auto-generated method stub
getMoney();
}
// 同步方法,默认使用this作为钥匙
public synchronized void getMoney() {
System.out.println(Thread.currentThread().getName() + "qule" + getMoney);
curMoney += getMoney;
int temp = saveMoney - getMoney;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
saveMoney = temp;
times++;
//System.out.println(times);
}
public void show() {
System.out.println("yinhanghaiyou" + saveMoney + "jialihaiyou" + curMoney);
}
}
}
正常运行的时候会卡死在while循环那里,Debug模式下正常,如果在while循环内添加一条输出语句,程序也是正常的,求解是什么问题
public int getTimes() {
return times;
}
//times非volatile的,因此主线程调用该方法的时候,并不会要求刷新缓存,所以执行到 if (f.getTimes() >= 2) 的时候,条件一直不满足。
你将times的定义加上volatile看下就对了。
至于为何debug或则加上sysout后就正确,我估计是因为由于加长了主线程的执行时间,导致主线程的缓存被刷新了。
这可奇了,运行了好几遍,只有一种输出:
qiziqule2000
zhangfuqule2000
yinhanghaiyou6000jialihaiyou4000
不知卤煮问题如何来的?
分析了下,你的代码没有问题,锁同步代码也是正确的,需要改进的是你的getTimes方法操作了共享成员变量times,也需要同步处理,但是不影响执行结果。
我的开发环境是jdk1.8+Eclipse4.5,运行N>10次,结果为:
qiziqule2000
zhangfuqule2000
yinhanghaiyou6000jialihaiyou4000