java - 用 Java 实现 Peterson 锁

标签 java concurrency locking

我正在尝试实现 Peterson's algorithm在 Java 中,暂时创建了以下内容

public class Peterson {
    private volatile boolean[] flag = new boolean[2];
    private volatile int victim;

    public void lock(int id)
    {
        //System.out.println(id);
        int i = id;
        int j = 1 - id; 
        flag[i] = true;
        victim = i;
        while (flag[j] && victim == i) {};
    }

    public void unlock(int id)
    {
        flag[id] = false;
    }
}

我得到了以下代码来测试锁...

class Counter {
    private int value;

    public Counter(int c)   {
        value = c;
    }

    public int get()
    {
        return value;
    }

    public int getAndIncrement()    {       
        return value++;
    }
}


class Thread1 implements Runnable   {
    private Counter c;
    private int id;
    private List<Integer> values;
    private Peterson lock;

    public Thread1(Counter c, int id, List<Integer> values, Peterson l) {
        this.c = c;
        this.id = id;
        this.values = values;
        this.lock = l;
    }

    public void run() {

        while (true)
        {
            lock.lock(id);
            try {
                try {

                    if (c.get() > 20000)
                        return;

                    int n = c.getAndIncrement();
                    values.add(n);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            finally {
                lock.unlock(id);
            }
        }
    }
}

public class Tmp    {

    public static void main(String[] args) throws IOException   {

        Counter  c = new Counter(1);
        Thread[] t = new Thread[2];
        List<Integer> values = new ArrayList<Integer>();
        Peterson l =  new Peterson();

        for (int i = 0; i < t.length; ++i)  {
            t[i] = new Thread(new Thread1(c, i, values, l));
            t[i].start();
        }

        System.out.println(values.size());
    }
}

虽然我希望 System.out.println(values.size()); 打印 20000 但它在每次运行时打印不同的数字。为什么是这样?我做错了什么?

最佳答案

解锁时不会创建内存屏障,以保证之前发生

添加一个 volatile boolean barr并在unlock中写入true,并将lock中的while更改为while (barr && flag[j] &&victim == i) {};

这样你就不用等待你创建的线程了

for (int i = 0; i < t.length; ++i)  {
    t[i] = new Thread(new Thread1(c, i, values, l));
    t[i].start();
}

for (int i = 0; i < t.length; ++i)  {
    try{
        t[i].join();
    }catch(InterruptedException e){
        Thread.currentThread().interrupt();//don't expect it but good practice to handle anyway
    }
}

关于java - 用 Java 实现 Peterson 锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7167549/

相关文章:

Java运行时执行

java - 如何将函数与 javafx 中的 TreeView 子级关联

java - 我可以在 Service 类中使用 setter/getters 类吗?

java - 如何获取 java.util.concurrent.locks.Lock 的锁定/解锁状态

hibernate - 我们应该在 hibernate 查询中使用 LockOptions 而不是 LockMode 吗?

java - 无法关闭我的文件

c# - 同步并发 HttpClient 使用

c++ - c++ 图数据结构的并发垃圾收集

c++ - 为什么 pthread_key_create 析构函数被调用了几次?

mysql - 忽略 MySQL 查询中的锁定行