Java 同步对象锁定混淆
我正在学习K&B线程一章。我在读关于同步的书。这里有一个来自中国的例子 K&BJava 同步对象锁定混淆,java,multithreading,Java,Multithreading,我正在学习K&B线程一章。我在读关于同步的书。这里有一个来自中国的例子 K&B 公共类AccountDanger实现可运行{ 私人账户=新账户(); 公开募捐{ 对于(int x=0;x
公共类AccountDanger实现可运行{
私人账户=新账户();
公开募捐{
对于(int x=0;x<5;x++){
makedrawl(10);
if(account.getBalance()<0){
System.out.println(“账户透支”);
}
}
}
公共静态void main(字符串[]args){
AccountDanger AccountDanger=新AccountDanger();
螺纹1=新螺纹(accountDanger);
螺纹2=新螺纹(accountDanger);
一、设置名称(“Fred”);
二、设置名称(“露西”);
一、启动();
二、启动();
}
专用同步作废取款(整数金额){
如果(account.getBalance()>=金额){
System.out.println(Thread.currentThread().getName()+“将退出”);
试一试{
睡眠(500);
}
捕捉(中断异常e){
e、 printStackTrace();
}
账户提取(金额);
System.out.println(Thread.currentThread().getName()+“完成取款”);
}
否则{
System.out.println(“帐户中没有足够的“+Thread.currentThread().getName()+”来提取”+
account.getBalance());
}
}
}
K&B讨论了同步方法和同步块。这里是K&B的参考段落
当一个方法从同步块中执行代码时,代码
被称为在同步上下文中执行。当你
同步方法时,用于调用该方法的对象是
必须获取其锁的对象。但是当我们同步一块
代码中,必须指定要用作锁的对象的锁
那么在本例中,将在AccountDanger实例或Account对象上获取锁吗?
我想应该是这样的。我感觉正确吗?如果是危险物体,
如果一个线程已获得AccountDanger锁,那么其他线程是否能够调用非同步方法
在本例中,是否会在AccountDanger上获取锁
实例还是帐户对象
对。我经常看到的一个技巧是,当您只有一小段实际需要同步的代码时,就在上进行同步。例如:
int balance = -1;
synchronized(this) {
balance = account.getBalance();
account.withdraw(amt);
}
//IO, etc. after that.
一般来说,这会加快速度
private synchronized void makeWithdrawl(int amt){
//is implicitly acquiring lock on this object (AccountDanger object)
}
因此,在本例中,调用此方法的第一个线程将进入synchronized
块获取this
对象监视器并保持它,并且除了第一个线程本身之外,没有其他线程可以在this
上再次获取监视器锁。调用此方法的所有其他线程将阻塞,直到第一个线程释放锁并释放监视器
注意:用于同步块的锁本质上就是锁。是的,它位于AccountDanger对象上(隐式地,因为该方法具有synchronized关键字)。谢谢kayaman。那么,这是否意味着当一个线程获得了当前对象的锁时,没有其他线程可以访问任何其他非同步方法?不。这意味着其他线程不能访问其他同步方法。可以访问非同步方法,因为它们不受对象监视器的保护。
private synchronized void makeWithdrawl(int amt){
//is implicitly acquiring lock on this object (AccountDanger object)
}