[英]Java - Deadlock using SWAP function to solve mutual exclusion
我想使用Swap函数解决互斥问题,但是该程序存在死锁,而且我不知道为什么。 当线程连续两次执行时,似乎会出现问题。
交换锁逻辑:
每个线程都使用局部变量和共享变量。 线程首先锁定其局部变量(例如,假定值为1)。 当线程局部变量被解锁(例如,假设值为0)时,它可以执行关键部分,如果线程局部变量被锁定(例如,假设值为1),则线程处于繁忙等待状态 (繁忙等待测试了局部变量的解锁)并调用交换功能)
swap函数将局部变量设置为共享变量值,反之亦然。swap函数必须为ATOMIC。
当线程调用交换时,如果交换后“共享”变量为0(解锁),则共享变量为1, 局部变量为0。因此,只有该线程才能访问关键部分,而其他线程不能访问。
最后(不再需要关键部分),线程将共享变量解锁。
主要
public class Mutex {
public static void main(String []args){
LockVar var = new LockVar(0);
ThreadSwap th0 = new ThreadSwap(var);
ThreadSwap th1 = new ThreadSwap(var);
ThreadSwap th2 = new ThreadSwap(var);
th0.start();
th1.start();
th2.start();
}
}
线程类 (强调这种互斥锁的逻辑)
class ThreadSwap extends Thread{
private LockVar shared_var;
public ThreadSwap(LockVar var){
this.shared_var = var;
}
@Override
public void run(){
LockVar local = new LockVar(1);
while(true){
---> local.setVar(1);
---> while(local.getVar() == 1){Synch.SWAP(shared_var, local);}
System.out.println("Thread " + getId() + " exec critical section.");
// Critical section
System.out.println("Thread " + getId() + " is leaving critical section.");
---> shared_var.setVar(0);
}
}
}
交换功能
class Synch{
public static synchronized void SWAP(LockVar shared, LockVar local){
int temp = shared.getVar();
shared.setVar(local.getVar());
local.setVar(temp);
}
...
}
共享变量类
class LockVar{
private volatile int var;
public LockVar(int value){
this.var = value;
}
public int getVar(){
return this.var;
}
public void setVar(int value){
this.var=value;
}
}
想象一下这种情况:
shared.setVar(local.getVar());
(现在shared_var == 1)和local.setVar(temp);
(请记住,步骤2中的temp为1)。 产生了死锁:shared_var为1,并且临界区中没有线程。 这是因为SWAP不是原子的(监视器可以从执行同步方法的线程中移开,它只会不允许其他线程进入该方法,也不允许其他方法在同一锁上同步(对于静态方法而言,该类为此类) ,如果是非静态方法,则为对象的实例))。
为了解决此问题,您不应该允许SWAP执行时更改共享,方法是使其成为原子的。 一种可能是摆脱局部,并在AtomicBoolean上使用compareAndSet ,该AtomicBoolean目前将扮演shared_var的角色。
原子类型保证原子性和挥发性(请参阅文档 )。 这样,每个线程都应该获取用于信号发送的AtomicBoolean的引用(不好意思,不好意思),并使用compareAndSet原子地更新变量的值,这种方式对于其他线程是立即可见的:
import java.util.concurrent.atomic.AtomicBoolean;
public class Mutex {
public static void main(String []args){
AtomicBoolean isLocked = new AtomicBoolean(false);
ThreadSwap th0 = new ThreadSwap(isLocked);
ThreadSwap th1 = new ThreadSwap(isLocked);
ThreadSwap th2 = new ThreadSwap(isLocked);
th0.start();
th1.start();
th2.start();
}
}
class ThreadSwap extends Thread {
private AtomicBoolean shared_IsLocked;
public ThreadSwap(AtomicBoolean var){
this.shared_IsLocked = var;
}
@Override
public void run(){
while(true){
// While the flag is true (locked), keep checking
// If it is false (not locked), atomically change its value and keep going
while(!shared_IsLocked.compareAndSet(false, true));
System.out.println("Thread " + getId() + " exec critical section.");
// Critical section
System.out.println("Thread " + getId() + " is leaving critical section.");
shared_IsLocked.set(false);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.