Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同步对象锁定混淆_Java_Multithreading - Fatal编程技术网

Java 同步对象锁定混淆

Java 同步对象锁定混淆,java,multithreading,Java,Multithreading,我正在学习K&B线程一章。我在读关于同步的书。这里有一个来自中国的例子 K&B 公共类AccountDanger实现可运行{ 私人账户=新账户(); 公开募捐{ 对于(int x=0;x

我正在学习K&B线程一章。我在读关于同步的书。这里有一个来自中国的例子 K&B

公共类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)              
}