黑马程序员技术交流社区
标题:
多线程的安全问题之锁
[打印本页]
作者:
谢冬
时间:
2013-3-17 13:41
标题:
多线程的安全问题之锁
/*模拟银行取钱*/
public class Account {
//账户余额
private double balance;
public Account(double balance) {
this.balance = balance;
}
/*取钱的方法*/
public double drawBalance(double drawBalance)
{
balance = balance - drawBalance;
return balance;
}
/*查询余额*/
public double getBalance()
{
return balance;
}
}
复制代码
/*取钱的线程*/
public class DrawThread extends Thread
{
private Account a;
//要取的金额
private double drawBalance;
public DrawThread(String name, Account a, double drawBalance)
{
super(name);
this.a = a;
this.drawBalance = drawBalance;
}
public void run()
{
while(true){
synchronized(a){
if(a.getBalance() < drawBalance){
System.out.println(Thread.currentThread() + " : 余额不足,当前余额: " + a.getBalance());
break;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
a.drawBalance(drawBalance);
System.out.println(Thread.currentThread() + "取钱成功,取走金额:" + drawBalance + " ,当前余额:" + a.getBalance());
}
}
}
}
/*在主方法中运行*/
public class DrawTest {
public static void main(String[] args) {
Account a = new Account(1000);
new DrawThread("A账户:", a, 500).start();
new DrawThread("B账户:", a, 300).start();
}
}
复制代码
//当使用this或者其他对象作为锁的时候,为什么共享数据会出错?毕老爷说着个同步代码块的锁可以任意指定,我反复模拟了几个列子,都会出错,只有使用要操作的对象时作为锁时,测试结果才没问题
作者:
谢波
时间:
2013-3-17 14:35
线程同步加锁,一定要明确要操作的是共享数据是什么
只针对 操作共享数据的代码加锁
你的例子中,共享数据是balance 所以锁应该加在drawBalance和getBalance这两个方法上
在这两个方法上用this或者其他的锁是可以的
当你把锁加在两个线程中时,也是可以的
但是,无论在什么时候都必须保证锁对象是唯一的,也就是说要是同一把锁
如果用this,那么你总共创建了两个DrawThread对象,this代表的是对象本身,所以这时的两个this是不相等,不是同一把锁
用其他的对象作为锁也是一个道理,只要保证锁对象唯一就ok了
比如说,可以建立一个类 a 里面定义一个对象 public static Object lock= new Object();然后用这个lock作为他们的锁,都是可以的
作者:
罗威
时间:
2013-3-17 16:30
通俗点说就是:
new DrawThread("A账户:", a, 500).start();你new一次就创建了第一个对象
new DrawThread("B账户:", a, 300).start();你再new一次又创建了一个对象
this表示本类对象的引用,你创建了两个对象,每个对象都有一个不同的this锁,就说明你有两把锁了,当然就会出错 你想通了没?有什么问题可以继续追问!
作者:
陈丽莉
时间:
2013-3-17 19:34
若还有问题,请继续追问; 没有的话,请将帖子分类改成【已解决】~
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2