[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关键字, 把并行改为串行就可以了。
「真诚赞赏,手留余香」