gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 09:54:11 24 4
gpt4 key购买 nike

我整理了一些 Java 代码来演示线程中的死锁。就其本身而言,我通常会得到 2 行输出和一个异常,有时在预期的输出行之前,有时在输出行之后。我得到的异常是 transfer() 方法第一行的 NullPointerException。

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

Avoid Deadlock example

作为解决方案,我尝试了 Will Hartung 和 Dreamcash 发布的内容,但在尝试使用同步或 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;
}

}

Bank 类(单例):

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();
}

最佳答案

The exception I get is a NullPointerException on the first line of the transfer() method.

The problem I'm having is I'd like to know how to solve this deadlock problem.

您的代码不可能引发任何死锁。它确实引发了写入可见性问题:其中一个线程开始调用惰性 Bank 初始化程序,而另一个线程看不到写入。

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

我的结论是,最好的办法是阅读一些有关 Java 并发性的介绍 Material 。

关于Java 线程 - 死锁的解决方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20490577/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com