我已经汇总了一些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问题将通过添加synchronized
到getInstance
方法来解决,并且不会引入任何死锁.
我的结论是,您最好的办法是阅读一些关于Java并发性的介绍性材料.