Slipped Conditions
下文讲述“Slipped Conditions”的简介说明,如下所示:
例:
代码块1:运行wait操作直到isLocked变为false才退出
代码块2:将isLocked置为true,以此来锁住这个Lock实例避免其它线程通过lock()方法
Slipped Conditions简介说明
Slipped Conditions:一个线程检查某一特定条件到该线程操作此条件期间,这个条件已经被其它线程改变,导致第一个线程在该条件上执行了错误的操作例:
public class Lock {
private boolean isLocked = true;
public void lock(){
synchronized(this){
while(isLocked){
try{
this.wait();
} catch(InterruptedException e){
}
}
}
synchronized(this){
isLocked = true;
}
}
public synchronized void unlock(){
isLocked = false;
this.notify();
}
}
在以上的代码中,lock()方法中拥有两个同步块代码块1:运行wait操作直到isLocked变为false才退出
代码块2:将isLocked置为true,以此来锁住这个Lock实例避免其它线程通过lock()方法
当在某个时刻isLocked为false 此时有两个线程同时访问lock方法 如果第一个线程先进入第一个同步块,这个时候它会发现isLocked为false 若此时允许第二个线程执行,它也进入第一个同步块,同样发现isLocked是false 现在两个线程都检查了这个条件为false,然后它们都会继续进入第二个同步块中并设置isLocked为true --------------------------------------------------------------------------------------------------------------------------------------- 以上场景就是slipped conditions的示例 当两个线程检查同一个条件,然后退出同步块 因此在这两个线程改变条件之前,就允许其它线程来检查这个条件(条件被某个线程检查到该条件被此线程改变期间,这个条件已经被其它线程改变过了) --------------------------------------------------------------------------------------------------------------------------------------- 为避免slipped conditions,条件的检查与设置必须是原子的(在第一个线程检查和设置条件期间,不会有其它线程检查这个条件) 为解决以上的异常,我们只需将isLocked = true这行代码移到第一个同步块中,放在while循环后面即可例:
public class Lock {
private boolean isLocked = true;
public void lock(){
synchronized(this){
while(isLocked){
try{
this.wait();
} catch(InterruptedException e){
}
}
isLocked = true;
}
}
public synchronized void unlock(){
isLocked = false;
this.notify();
}
}
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


