一、介绍
我们模拟一个场景:多个游客要验证身份通过一道门
三个类:
1.Gate:相当于一个资源 调用一个方法pass 方法
2.User 是使用资源的地方,也就是每一个用户,或者说是通过门的游客
3.SingleClient 当User跑起来的时候不断的使用这个资源
二、代码实现
①.Gate类
package chapter2.singlegate;
/**
* @author czd
*/
public class Gate {
private int counter = 0;
private String name = " ";
private String address = " ";
/**
* 临界值也可以说是门
* @param name
* @param address
*/
public void pass(String name , String address){
counter++;
this.name = name;
this.address = address;
verify();
}
@Override
public String toString() {
return "Gate{" +
"counter=" + counter +
", name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
/**
* 判断符合条件的名字和地址
* if语句可以按照需求改
*/
private void verify(){
if (this.name.charAt(0) != this.address.charAt(0)){
System.out.println("Error:" + toString());
}
}
}
②.User类
package chapter2.singlegate;
/**
* @author czd
*/
public class User extends Thread {
private Gate gate;
private String name;
private String address;
public User(String name , String address , Gate gate){
this.name = name;
this.address = address;
this.gate = gate;
}
@Override
public void run() {
System.out.println(name + ">>>>>can into the gate");
while (true){
gate.pass(name , address);
}
}
}
③.SingleClient类
在这里插入代码片
package chapter2.singlegate;
/**
* @author czd
*/
public class SingleClient {
public static void main(String[] args) {
Gate gate = new Gate();
User bj = new User("Bei" , "Beijing" , gate);
User sh = new User("Shang" , "Shanghai" , gate);
User gz = new User("Guang" , "GuangZhou" , gate);
bj.start();
sh.start();
gz.start();
}
}
输出结果
三、提出问题:我们看到明明相等但是它却输出出来了,这是为什么?
原因:
也就是说它明明判断相等了,但是在toString的时候领外一个线程又把他修改了,所以输出结果出现了问题,
这就是在多线程中出现了不安全的操作,
多线程编程的三个问题,1工共享资源,也就是Gate, 有操作(pass)就会发生竞争 ,有临界值(有临界值就会有资源竞争)
四、解决方案
在pass方法上加上this锁即可,即加上synchronized关键字
这样就是说它资源每次访问只能有一个线程通过