Chr*_*ris 1 java multithreading deadlock thread-safety
我已经汇总了一些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;
}
}
Run Code Online (Sandbox Code Playgroud)
银行等级(单身人士):
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;
}
}
Run Code Online (Sandbox Code Playgroud)
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());
}
}
Run Code Online (Sandbox Code Playgroud)
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());
}
}
Run Code Online (Sandbox Code Playgroud)
最后,我的主要方法
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();
}
Run Code Online (Sandbox Code Playgroud)
我得到的异常是transfer()方法第一行的NullPointerException.
我遇到的问题是我想知道如何解决这个死锁问题.
您的代码无法引发任何死锁.它引发的是写入可见性问题:其中一个线程调用惰性Bank初始化器而另一个线程看不到写入.
要获得死锁,首先需要任何类型的锁定(synchronized关键字).您的特定NPE问题将通过添加synchronized到getInstance方法来解决,并且不会引入任何死锁.
我的结论是,您最好的办法是阅读一些关于Java并发性的介绍性材料.
| 归档时间: |
|
| 查看次数: |
1575 次 |
| 最近记录: |