Single Thread Execution设计模式

Single Thread Execution设计模式:同一时刻只允许一个线程访问共享资源。

synchronized关键字虽然可以保证single Thread Execution,但是使用不当可能会导致死锁。

死锁场景示例:吃面问题,A手持刀等待B放下叉,B手持叉等待A放下刀。

public class Tableware {
    //餐具名称
    private final String toolName;

    public Tableware(String toolName){
         this.toolName = toolName;
    }

    @Override
    public String toString() {
        return "Tool" + toolName;
    }

}
public class EatNoodleThread extends Thread{

    private String name;

    private final Tableware leftTool;

    private  final Tableware rightTool;

    public EatNoodleThread(String name,Tableware leftTool,Tableware rightTool){
        this.name = name;
        this.leftTool = leftTool;
        this.rightTool = rightTool;
    }

    @Override
    public void run() {
        while(true){
            this.eat();
        }
    }

    private void eat(){
        synchronized (leftTool){
            System.out.println(name + " take up " + leftTool + "(left)");
            synchronized (rightTool){
                System.out.println(name + " take up " + rightTool + "(right)");
                System.out.println(name + " is eating now");
                System.out.println(name + " put down " + rightTool + "(right)");
            }
            System.out.println(name + " put down " + leftTool + "(left)");
        }
    }

    public static void main(String args[]){
        Tableware fork = new Tableware("fork");
        Tableware knife = new Tableware("knife");
        new EatNoodleThread("A",fork,knife).start();
        new EatNoodleThread("B",knife,fork).start();

    }
}

运行结果:双方僵持,都在等待对方放下

......

这种就是典型的交叉锁导致两个线程相互等待对方放下锁而发生死锁的情况,解决这种情况,需要将刀叉进行封装:

public class TablewarePair {

    private final Tableware leftTool;

    private  final Tableware rightTool;

    public TablewarePair(Tableware leftTool,Tableware rightTool){
        this.leftTool = leftTool;
        this.rightTool = rightTool;
    }

    public Tableware getLeftTool() {
        return leftTool;
    }

    public Tableware getRightTool() {
        return rightTool;
    }
}
public class EatNoodleThread extends Thread{

    private String name;

    private TablewarePair tablewarePair;

    public EatNoodleThread(String name,TablewarePair tablewarePair){
        this.name = name;
        this.tablewarePair = tablewarePair;
    }

    @Override
    public void run() {
        while(true){
            this.eat();
        }
    }

    private void eat(){
        synchronized (tablewarePair){
            System.out.println(name + " take up " + tablewarePair.getLeftTool() + "(left)");
            System.out.println(name + " take up " + tablewarePair.getRightTool() + "(right)");
            System.out.println(name + " is eating now");
            System.out.println(name + " put down " + tablewarePair.getRightTool() + "(right)");
            System.out.println(name + " put down " + tablewarePair.getLeftTool() + "(left)");
        }
    }

    public static void main(String args[]){
        Tableware fork = new Tableware("fork");
        Tableware knife = new Tableware("knife");
        TablewarePair tablewarePair = new TablewarePair(fork,knife);
        new EatNoodleThread("A",tablewarePair).start();
        new EatNoodleThread("B",tablewarePair).start();

    }
}

测试结果正常:

......

...... 

将某个类设计成线程安全的类,用Single Thread Execution控制是其中的方法之一。若是子类继承线程安全的类并且打破了 Single Thread Execution,就会破坏方法的安全性,这种情况一般称为异常继承。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值