单线程执行-设计模式

Posted by 麦子 on Tuesday, 2019年12月03日

[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关键字, 把并行改为串行就可以了。

「真诚赞赏,手留余香」

真诚赞赏,手留余香

使用微信扫描二维码完成支付