首先,我在这里很新,所以我希望在提问过程中我能做好所有事情。
问题:
我的课程Store
的属性为int size;
在这个类中有两种操作size
属性的方法。
`public synchronized void leave(){
this.size++;
}`
`public synchronized void enter(){
while(this.size==0){ }
this.size--;
}`
如果我使用size=2;
和其他4个对象(4个线程)初始化存储对象
交替尝试leave()
或enter()
Store object
我将获得无限循环。
我想如果我编写同步方法,也可以通过线程调用leave方法,尽管其他线程会在无限循环中挂起。
我希望我的问题是可以理解的。 非常感谢你的帮助。
答案 0 :(得分:2)
首先,我在这里很新,所以我希望我能做好一切 在质疑期间。
你的问题很好,所以你至少得到了正确的答案:)
其他4个对象(4个线程)交替尝试离开()或 输入()Store对象我将获得无限循环
当一个线程进入同步块时,您声明在线程离开初始同步块之前,没有其他线程可以进入同一对象的同步区域。你有一个线程调用enter
并旋转直到大小为0.为此,大小需要增加,这是不可能的,因为另一个线程无法调用leave
(而另一个线程正在旋转永远)。
<强>解决方案强>
在监视器上放置线程while(<some condition>){ }
,而不是忙于旋转(wait
)。这将放弃锁定,以便另一个线程可以进入。在leave
之后,通知任何等待的线程。
public synchronized void leave(){
this.size++;
this.notify();
}
public synchronized void enter(){
while(this.size==0){
this.wait();
}
this.size--;
}
答案 1 :(得分:0)
与其他解决方案相同,您也可以考虑以下解决方案。两件事情更好 1.而不是同步方法减少锁定范围 2.使用wait-notify解决方案感谢非常明确的方法
class ConditionExample {
final Lock lock = new ReentrantLock();
final Condition resourceAvailable = lock.newCondition();
private int size = 2;
public void leave() throws InterruptedException {
lock.lock();
try {
size++;
//signal other waiting threads
resourceAvailable.signal();
} finally {
lock.unlock();
}
}
public void enter() throws InterruptedException {
lock.lock();
try {
//Check condition
while (size == 0)
resourceAvailable.await();
size--;
} finally {
lock.unlock();
}
}
}
希望这有帮助。