Java 使用3个PetersonLock数组同步4个进程

Java 使用3个PetersonLock数组同步4个进程,java,multithreading,concurrency,synchronization,locking,Java,Multithreading,Concurrency,Synchronization,Locking,假设我们有类PetersonLock,如下所示: class PetersonLock { AtomicBoolean flag[] = new AtomicBoolean[2]; volatile int victim; public void Acquire(int id) { flag[id].set(true); victim = id; while (flag[1-id].get() &&a

假设我们有类PetersonLock,如下所示:

class PetersonLock {
     AtomicBoolean flag[] = new AtomicBoolean[2];
     volatile int victim;

     public void Acquire(int id) {

         flag[id].set(true);
         victim = id;
         while (flag[1-id].get() && victim == id);
    }

    public void Release(int id) {
         flag[id].set(false);
    }
}
其中id为1或0。我现在有了下面的类,它在4个进程中分层使用3个PetersonLock

class Lock4Pete{

    PetersonLock[] lock = new PetersonLock[3];

    public void Acquire(int id) {

         lock[0].Acquire(id/2);
         lock[1+id/2].Aquire(id%2);
    }

    public void Release(int id) {

         lock[1+id/2].Release(id%2);
         lock[0].Release(id/2);
    }
  }
其中,id为0、1、2或3

我不明白这背后的想法,我也不知道如何修复这段代码。我不知道他们在这里想干什么。为什么4个进程需要3个锁,为什么每个进程都可以使用锁[0]


如果能帮上点忙,我将不胜感激。这不是家庭作业,而是一个我不太理解的练习。

这4个线程被分成2个容器,每个容器包含2个线程
id/2
指定线程所属的bin,而
id%2
指定其bin内线程的索引

让我们重写代码,将
id/2
id%2
作为单独的变量处理

class Lock4Pete {

    // This lock determines the active bin.
    PetersonLock masterLock = new PetersonLock;

    // Each of these locks guards the corresponding bin.
    PetersonLock[] binLocks = new PetersonLock[2];

    public void Acquire(int bin, int index) {
        // After this line is executed in one of the threads, 
        // any thread from a *different* bin will have to wait 
        // until this thread calls masterLock.Release(bin);  
        // before it can execute masterLock.Acquire(another_bin);
        masterLock.Acquire(bin);

        // It is possible that more than one thread reaches this point 
        // simultaneously, but they are guaranteed to be from the same bin.
        // Now we only need to make sure that threads from that bin can 
        // neither acquire the lock simultaneously nor come to a deadlock.

        // After this line is executed, 
        // any thread from the *same* bin will have to wait until 
        // this thread calls binLocks[bin].Release(index); 
        // before it can execute binLocks[bin].Aquire(another_index);
        binLocks[bin].Aquire(index);

        // Thus, only one thread at a time can reach the end of this
        // method and acquire the lock.
    }

    public void Release(int bin, int index) {
         binLocks[bin].Release(index);
         masterLock.Release(bin);
    }
}

我不想做那种运动。代码被破坏了,有打字错误,格式暴露了作者不是一个全面的Java开发人员……这更多的是一个概念练习,而不是Java练习。我正试图找出算法的错误以及如何修复它。这里我们并不关心java的细节。你可以把它当作伪代码来读。你看到了什么打字错误?嗯,
AtmonicBoolesn
现在。这很有趣。谢谢你详尽的回答。您是否同意我给出的实现的主要问题是锁[0]可以同时由所有4个进程驱动?因此,如果我们只是简单地改变顺序,那么它就会起作用。像这样,我们将首先设置一个“垃圾箱”processes@DariusTheGreat对我来说,这个命令似乎是正确的<代码>锁[0]一次只能由两个线程保持:要么
0
1
,要么
2
3
。例如,
Acquire(2);释放(2)执行以下操作:1)锁定存储箱
1
(因此线程
0
1
必须等待它被释放);2) 锁定bin
1
中的索引
0
(因此线程
3
必须等待它被释放);3) 解锁bin
1
中的索引
0
(现在线程
3
可以自由获取锁);4) 解锁箱子
1
(现在线程
0
1
也可以自由获取锁)。