[英]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.