根据在线教程,我提出了以下守卫暂停代码。
public synchronized String method1() throws InterruptedException {
lock = true;
Thread.sleep(17000);
lock = false;
notifyAll();
return "Method1";
}
public synchronized String method2() throws InterruptedException {
while(lock) {
wait();
}
Thread.sleep(3000);
return "From Method 2";
}
从多个线程同时调用上述两个方法。
从上面的例子中,在wait()的前置条件中使用的锁定变量是否为真?
因为使用synchronized关键字,所以两种方法都是互斥的。
以上示例是否适用于受保护的暂停?
我们什么时候需要看守?
答案 0 :(得分:0)
实例方法上使用的 Java 关键字synchronized
确保一次只有一个线程将在具有方法修饰符synchronized
的单个实例上执行任何方法好。更精确:不仅在任何方法上,而且在使用与监视器或信号量相同的实例的任何资源/数据上进行相互独占访问控制。
在您的示例中,两个实例方法都具有修饰符synchronized
,因此将确保在任何给定时间只有一个线程在任何这些方法中执行代码。
变量lock
在您的示例中没有用,因为将其设置为true
的相同方法会将其更改回false
。因此,method2
永远不会将lock
视为true
。
每当多个线程必须在可变资源上运行并且两个线程都应该同意读取/操作状态时,您必须保护此资源免受竞争条件的影响(同时读取或修改)。否则,如果由单个线程执行,结果可能会有所不同。
答案 1 :(得分:0)
我认为,您的实施不正确,因为您在同一方法中执行lock = true;
和lock = flase;
。
在我看来,必须像下面这样做,
public synchronized String method1() throws InterruptedException {
Thread.sleep(17000);
lock = false;
notifyAll();
return "Method1";
}
public synchronized String method2() throws InterruptedException {
while(lock) {
wait();
}
Thread.sleep(3000);
lock = true;
return "From Method 2";
}
您必须明白,除了可以使用同步锁之外,还需要满足前提条件的情况下, Guarded Suspension 是一种模式。
e.g。当要实现一个线程安全的阻塞队列时,如果没有可用的项目,我们需要将take()
方法线程置于等待状态,如果队列已满,put
方法线程也处于等待状态。因此除了同步访问之外还需要这个要求,即需要以相互排斥的方式访问队列(这是一个主要要求,因此您将synchronized
置于方法签名上)但是如果队列未处于正确状态(通过检查)前置条件变量),您执行wait
或notify
等。
您还必须记住Thread.sleep(...)
在Object.wait()
执行时不会释放同步锁定。
拿一个真实的例子(就像一个线程安全的阻塞队列)然后我们可以判断你的实现是否正确 - 它无法判断你的实现是否正确(除了指出{ {1}}不应该以相同的方法设置/重置)因为没有这种模式的通用实现。
希望它有所帮助!!