public class Account { private String accountNo; private double balance; public Account(String accountNo,double balance){ this.accountNo=accountNo; this.balance=balance; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public String getAccountNo() { return accountNo; } public void setAccountNo(String accountNo) { this.accountNo = accountNo; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Account account = (Account) o; return accountNo.equals(account.accountNo); } @Override public int hashCode() { return accountNo.hashCode(); } }
public class DrawThread extends Thread { private Account account; private double drawAmount; public DrawThread(String name, Account account, double drawAmount) { super(name); this.account = account; this.drawAmount = drawAmount; } public void run(){ synchronized (account){ if(account.getBalance()>=drawAmount){ System.out.println(getName() + "取钱成功,吐出钞票: " + drawAmount); try{ Thread.sleep(1); }catch(InterruptedException ex){ ex.getStackTrace(); } account.setBalance(account.getBalance()-drawAmount); System.out.println("\t余额为:"+account.getBalance()); }else{ System.out.println(getName()+"取钱失败,余额不足"); } } } }
public class DrawTest { public static void main(String[] args){ Account acct=new Account("1234567",1000); new DrawThread("甲",acct,800).start(); new DrawThread("乙",acct,800).start(); } }
public class DrawThread extends Thread { private Account account; private double drawAmount; public DrawThread(String name, Account account, double drawAmount) { super(name); this.account = account; this.drawAmount = drawAmount; } public void run(){ // synchronized (account){ if(account.getBalance()>=drawAmount){ System.out.println(getName() + "取钱成功,吐出钞票: " + drawAmount); try{ Thread.sleep(1); }catch(InterruptedException ex){ ex.getStackTrace(); } account.setBalance(account.getBalance()-drawAmount); System.out.println("\t余额为:"+account.getBalance()); }else{ System.out.println(getName()+"取钱失败,余额不足"); } // } } }
会出现这些情况的结果:
public class Account { private String accountNo; private double balance; public Account(String accountNo,double balance){ this.accountNo=accountNo; this.balance=balance; } //因为账户余额不可以随便更改,所以只为balance提供getter方法 public double getBalance() { return balance; } public String getAccountNo() { return accountNo; } public void setAccountNo(String accountNo) { this.accountNo = accountNo; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Account account = (Account) o; return accountNo.equals(account.accountNo); } @Override public int hashCode() { return accountNo.hashCode(); } //提供一个线程安全的draw()方法来完成取钱操作 public synchronized void draw(double drawAmount){ if(balance>=drawAmount){ System.out.println(Thread.currentThread().getName()+"取钱成功!吐出钞票:"+drawAmount); try{ Thread.sleep(1); }catch (InterruptedException ex){ ex.printStackTrace(); } balance-=drawAmount; System.out.println("\t余额为:"+balance); }else{ System.out.println(Thread.currentThread().getName()+"取钱失败,余额不足"); } } }
public class DrawThread extends Thread { private Account account; private double drawAmount; public DrawThread(String name, Account account, double drawAmount) { super(name); this.account = account; this.drawAmount = drawAmount; } public void run(){ account.draw(drawAmount); } }
public class DrawTest { public static void main(String[] args){ Account acct=new Account("1234567",1000); new DrawThread("甲",acct,800).start(); new DrawThread("乙",acct,800).start(); } }
class X{ //定义锁对象 private final ReentrantLock lock=new ReentrantLock(); //定义需要保证线程安全的方法 public void m(){ //加锁 lock.lock(); try{ //...method body } //使用finally块来保证释放锁 finally{ lock.unlock(); } } }
public class Account { private final ReentrantLock lock=new ReentrantLock(); private String accountNo; private double balance; public Account(String accountNo,double balance){ this.accountNo=accountNo; this.balance=balance; } //因为账户余额不可以随便更改,所以只为balance提供getter方法 public double getBalance() { return balance; } public String getAccountNo() { return accountNo; } public void setAccountNo(String accountNo) { this.accountNo = accountNo; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Account account = (Account) o; return accountNo.equals(account.accountNo); } @Override public int hashCode() { return accountNo.hashCode(); } //提供一个线程安全的draw()方法来完成取钱操作 public void draw(double drawAmount){ //加锁 lock.lock(); try { if (balance >= drawAmount) { System.out.println(Thread.currentThread().getName() + "取钱成功!吐出钞票:" + drawAmount); try { Thread.sleep(1); } catch (InterruptedException ex) { ex.printStackTrace(); } balance -= drawAmount; System.out.println("\t余额为:" + balance); } else { System.out.println(Thread.currentThread().getName() + "取钱失败,余额不足"); } }finally { lock.unlock(); } } }
class A{ public synchronized void foo(B b){ System.out.println("当前线程名为:"+Thread.currentThread().getName()+"进入了A实例的foo()方法"); try{ Thread.sleep(200); }catch(InterruptedException ex){ ex.printStackTrace(); } System.out.println("当前线程名为:"+Thread.currentThread().getName()+"试图调用B实例的last()方法"); b.last(); } public synchronized void last(){ System.out.println("进入了A类的last()方法内部"); } } class B{ public synchronized void bar(A a){ System.out.println("当前线程名为:"+Thread.currentThread().getName()+"进入了B实例的bar()方法"); try{ Thread.sleep(200); }catch(InterruptedException ex){ ex.printStackTrace(); } System.out.println("当前线程名为:"+Thread.currentThread().getName()+"试图调用A实例的last()方法"); a.last(); } public synchronized void last(){ System.out.println("进入了B类的last()方法内部"); } } public class DeadLock implements Runnable{ A a =new A(); B b=new B(); public void init(){ Thread.currentThread().setName("主线程"); a.foo(b); System.out.println("进入了主线程之后..."); } public void run(){ Thread.currentThread().setName("副线程"); b.bar(a); System.out.println("进入了副线程之后..."); } public static void main(String[] args){ DeadLock d1=new DeadLock(); new Thread(d1).start(); d1.init(); } }
结果: