[TOC]
转载地址:https://blog.csdn.net/weixin_39715061/article/details/81065182
模拟场景
很多游客同时通过一个门闸,实现一次只能通过一个的效果。 也就是synchronize的使用。
User游客
public class User implements Runnable {
    private final String myname;
    private final String myAddress;
    public Gate gate;
     
    public User(String myname, String myAddress, Gate gate) {
        this.myname = myname;
        this.myAddress = myAddress;
        this.gate = gate;
    }
    @Override
    public void run() {
        System.out.println(myname+"-->BEGEN***");
        while (true) {
            this.gate.pass(this.myname,this.myAddress);
        }
    }
    public static void main(String[] args) {
        Gate gute = new Gate();
        User bj =new User("小A","A",gute);
        User sh =new User("小B","B",gute);
        User sx =new User("小C","C",gute);
    
        Thread t_A = new Thread(bj);
        Thread t_B = new Thread(sh);
        Thread t_C = new Thread(sx);
        t_A.start();
        t_B.start();
        t_C.start();
    }
}
Gate门闸
public class Gate {
    private int counter;
    private String name = "Nobody";
    private String address = "Nowhere";
    // 临界值
    // 门里面的一个方法
    public void pass(String name, String address) {
        this.counter++;
        // 因为他是公共资源, 在这个地方赋值的时候, this.name 和 this.address 值有可能被其他线程覆盖。
        this.name = name;
        this.address = address;
        verify();
    }
    // 通过的方法
    private void verify() {
        if (this.name.contains(this.address) != true) {
            System.out.println("********BROKE----->" + this.name+"-->"+this.address);
        }
    }
}
运行结果
小A-->BEGEN***
小C-->BEGEN***
小B-->BEGEN***
********BROKE----->小A-->A
********BROKE----->小B-->A
********BROKE----->小C-->C
********BROKE----->小A-->A
可以看到, 上面中 小A无法通过A门闸。
分析原因
 public void pass(String name, String address) {
        this.counter++;
        // 因为他是公共资源, 在这个地方赋值的时候, this.name 和 this.address 值有可能被其他线程覆盖。
        this.name = name;
        this.address = address;
        verify();
    }
在这个方法加入synchronize关键字, 把并行改为串行就可以了。
「真诚赞赏,手留余香」