简体   繁体   English

Java-使用SWAP功能解决互斥的死锁

[英]Java - Deadlock using SWAP function to solve mutual exclusion

I would like to solve mutual exclusion using the Swap function but the program suffer from deadlock and I don't know why. 我想使用Swap函数解决互斥问题,但是该程序存在死锁,而且我不知道为什么。 It seems the problem occur when a thread exec two consecutive times. 当线程连续两次执行时,似乎会出现问题。

The swap lock logic: 交换锁逻辑:

Every thread make use of a local variable and a shared variable. 每个线程都使用局部变量和共享变量。 A thread at first lock its local variable (eg assume 1 value). 线程首先锁定其局部变量(例如,假定值为1)。 When a thread local variable is unlocked (eg assume 0 value) it can execute the critical section, if the thread local variable is locked (eg assume 1 value) the thread is in a busy-waiting (the busy waiting tests the local variable unlocking and calls the swap function) 当线程局部变量被解锁(例如,假设值为0)时,它可以执行关键部分,如果线程局部变量被锁定(例如,假设值为1),则线程处于繁忙等待状态 (繁忙等待测试了局部变量的解锁)并调用交换功能)

The swap function sets the local variable to the shared variable value and viceversa.The swap function has to be ATOMIC. swap函数将局部变量设置为共享变量值,反之亦然。swap函数必须为ATOMIC。

When a thread call swap, if the the "shared" variables is 0 (unlock) after swap we have that shared variable is 1 and the local to 0. So only that thread can access to the critical section no others. 当线程调用交换时,如果交换后“共享”变量为0(解锁),则共享变量为1, 局部变量为0。因此,只有该线程才能访问关键部分,而其他线程不能访问。

At the end (no more critical section) the thread unlock the shared variable. 最后(不再需要关键部分),线程将共享变量解锁。

Main 主要

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();
    }
}

Thread Class (The logic of this type of mutex is emphasized) 线程类 (强调这种互斥锁的逻辑)

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);
        }
    }
}

Swap function 交换功能

class Synch{
public static synchronized void SWAP(LockVar shared, LockVar local){
    int temp = shared.getVar();
    shared.setVar(local.getVar());
    local.setVar(temp);
}
...
}

Shared var Class 共享变量类

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;
    }
}

Imagine this scenario: 想象一下这种情况:

  1. The first thread swaps local and shared_var. 第一个线程交换本地和shared_var。 Now shared_var is 1 and local is 0. 现在shared_var为1,local为0。
  2. Since the synchronization on SWAP is on the Synch class, as soon as the first thread is done with SWAP, Thread 2 can get into it. 由于SWAP上的同步是在Synch类上的,因此第一个线程使用SWAP完成后,线程2即可进入。 Thread 2 makes temp = 1, and at that point the monitor switches back to Thread 1. 线程2使temp = 1,这时监视器切换回线程1。
  3. Thread 1 finishes the first iteration of the loop, printing the messages of exec and leaving critical section and setting shared_var = 0. Monitor moves to Thread 2. 线程1完成循环的第一次迭代,打印exec消息并离开关键部分并设置shared_var =0。监视器移至线程2。
  4. Thread 2 proceeds with SWAP. 线程2继续进行SWAP。 where it left it. 它留在哪里。 It executes shared.setVar(local.getVar()); 它执行shared.setVar(local.getVar()); (now shared_var == 1) and local.setVar(temp); (现在shared_var == 1)和local.setVar(temp); (remember temp is 1 from step 2). (请记住,步骤2中的temp为1)。

The deadlock has been produced: shared_var is 1 and no thread is in the critical section. 产生了死锁:shared_var为1,并且临界区中没有线程。 This is because SWAP is not atomic (the monitor can move away from a thread executing a synchronized method, it will just not allow other threads to enter such method nor others method synchronized on the same lock (the class in the case of a static method, the instance of the object in the case of a non-static method)). 这是因为SWAP不是原子的(监视器可以从执行同步方法的线程中移开,它只会不允许其他线程进入该方法,也不允许其他方法在同一锁上同步(对于静态方法而言,该类为此类) ,如果是非静态方法,则为对象的实例))。

In order to fix this you should not allow shared to change while SWAP is executing, by finding a way of making it atomic. 为了解决此问题,您不应该允许SWAP执行时更改共享,方法是使其成为原子的。 A possibility would be to get rid of local and use compareAndSet on an AtomicBoolean which would play the role of shared_var at the moment. 一种可能是摆脱局部,并在AtomicBoolean上使用compareAndSet ,该AtomicBoolean目前将扮演shared_var的角色。

Atomic types guarantee atomicity and volatility (see documentation ). 原子类型保证原子性和挥发性(请参阅文档 )。 This way, every thread should get a reference (excuse my loose nomenclature) to the AtomicBoolean used for signaling and use compareAndSet to atomically update the value of the variable in a way that is visible immediately to the other threads: 这样,每个线程都应该获取用于信号发送的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM