Peterson lock互斥

Peterson lock是并发中实现两个线程互斥的经典算法

// 假设两个thread的id分别为0,1
public class Peterson {
    private volatile boolean[] flag = new boolean[2];
    private volatile int last;  // 声明为volatile保证last在线程间的可见性

    public void lock() {
        int i = Thread.currentThread().getId();
        int j = 1-i;
        flag[i] = true; [1]  // flag[j]==true;   [4]
        last = i;       [2]  // last = j;        [5]
        while(flag[j] && i == last){}   //[3] // [6]
    }

    public void unlock() {
        int i = Thread.currentThread().getId();
        flag[i] = false;
    }
}

该算法实现互斥的关键是last无法同时即等于i又等于j(由volatile保证)。
假设有线程A与线程B,[1][2][3]为线程A的执行步骤,[4][5][6]为线程B的执行步骤,若线程A与线程B同时调用lock(),对于线程A可见的执行顺序有:

  1. [2]->[5]->[3],此时对于线程A有 (flag[j]==true && i==last)为false 线程A往下执行,对于线程B(flag[i]==true && j==last)为true,线程B在[6]处死循环知道线程A调用unlock()。
  2. [2]->[3]->[5],此时对于线程A若[4]先于[2][3]执行则有 (flag[j]==true && i==last)为true,线程A死循环,对于线程B有(flag[i]==true && j==last)为false线程B往下执行;若[4]后于[2][3]执行则有(flag[j]==false && i==last)为false,线程A往下执行,对于线程B有(flag[i]==true && j==last)为true,死循环。

    此外,通过将last声明为volatile防止了[1][2]的重排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值