Java线程 - 死锁的解决方案?

 mobiledu2502911797 发布于 2023-02-11 18:48

我已经汇总了一些Java代码,它们演示了线程中的死锁.就它本身而言,我通常得到2行输出和一个异常,有时在输出行之前和有时之后是预期的.我得到的异常是transfer()方法第一行的NullPointerException.

我遇到的问题是我想知道如何解决这个死锁问题.我已经在StackOverflow上搜索了这个问题并找到了这个页面:

避免死锁示例

作为解决方案,我尝试过Will Hartung和Dreamcash发布的内容,但在尝试使用synchronize或ReentrantLock对象时仍然会遇到异常.

这是代码:

帐户类:

public class Account {

    int id;
    double balance;

    public Account(int id, double balance){
        this.id = id;
        this.balance = balance;
    }

    public void withdraw(double amount){
        balance = balance - amount;
    }

    public void deposit(double amount){
        balance = balance + amount;
    }

    public int getID(){
        return id;
    }

    public double getBalance(){
        return balance;
    }

}

银行等级(单身人士):

public class Bank{

    static Bank bank;

    Account a1;
    Account a2;

    private Bank(){}

    public static Bank getInstance(){
        if(bank==null){
            bank = new Bank();
            bank.setAccountOne(new Account(1, 100));
            bank.setAccountTwo(new Account(2, 100));
        }

        return bank;
    }


    public void transfer(Account from, Account to, double amount){
        from.withdraw(amount);
        to.deposit(amount);
    }


    public Account getAccountOne(){
        return a1;
    }

    public Account getAccountTwo(){
        return a2;
    }
    public void setAccountOne(Account acc){
        a1 = acc;
    }
    public void setAccountTwo(Account acc){
        a2 = acc;
    }

}

PersonOne类:

public class PersonOne implements Runnable {

    public void run() {

        Bank bank = Bank.getInstance();     

        Account a1 = bank.getAccountOne();
        Account a2 = bank.getAccountTwo();

        bank.transfer(a2, a1, 10);      

        System.out.println("T1: New balance of A1 is " + a1.getBalance());
        System.out.println("T1: New balance of A2 is " + a2.getBalance());
    }

}

PersonTwo类:

public class PersonTwo implements Runnable {

    public void run() {
        Bank bank = Bank.getInstance();
        Account a1 = bank.getAccountOne();
        Account a2 = bank.getAccountTwo();

        bank.transfer(a1, a2, 10);

        System.out.println("T2: New balance of A1 is " + a1.getBalance());
        System.out.println("T2: New balance of A2 is " + a2.getBalance());
    }

}

最后,我的主要方法

    public static void main(String[] args){
        PersonOne p1 = new PersonOne();
        PersonTwo p2 = new PersonTwo();

        Thread t1 = new Thread(p1);
        Thread t2 = new Thread(p2);

        t1.start();
        t2.start();
    }

Marko Topoln.. 8

我得到的异常是transfer()方法第一行的NullPointerException.

我遇到的问题是我想知道如何解决这个死锁问题.

您的代码无法引发任何死锁.它引发的是写入可见性问题:其中一个线程调用惰性Bank初始化器而另一个线程看不到写入.

要获得死锁,首先需要任何类型的锁定(synchronized关键字).您的特定NPE问题将通过添加synchronizedgetInstance方法来解决,并且不会引入任何死锁.

我的结论是,您最好的办法是阅读一些关于Java并发性的介绍性材料.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有