ReentrantLock的使用
一、使用ReentrangLock实现多线程同步
例子:模拟妻子和丈夫去取钱,银行卡余额为100元,两个人同时取100元,那么最终余额应该是0元,有一个人取不出钱。
package com.cy.test.lock; public class Account implements Runnable { private int money = 100; //账户上默认有100元 //取钱 public void draw() { int balance = money; //当前余额 if (balance > 0) { for(int i=0; i<10000; i++){ } money = money - 100; //取走100元 System.out.println("当前余额为" + balance +"元," + Thread.currentThread().getName() + "取走100元,还剩" + money + "元"); } } @Override public void run(){ draw(); } }
妻子和丈夫分别来取钱,那么如果其中一人取走100元,另一个应该就没法取钱了,因为余额为0了。
package com.cy.test.lock; public class TestReentrantLock { public static void main(String[] args) { Account account = new Account(); Thread wife = new Thread(account, "wife"); Thread husband = new Thread(account, "husband"); //妻子取钱 wife.start(); //丈夫取钱 husband.start(); } }
console打印:
当前余额为100元,wife取走100元,还剩-100元
当前余额为100元,husband取走100元,还剩-100元
运行上面main方法,查看结果,很明显,出问题了,余额变成-100了。
这就是多线程造成的问题。
下面使用ReentrantLock来解决
package com.cy.test.lock; import java.util.concurrent.locks.ReentrantLock; public class Account implements Runnable { private int money = 100; //账户上默认有100元 private ReentrantLock lock = new ReentrantLock(); //取钱 public void draw() { try{ lock.lock(); int balance = money; //当前余额 if (balance > 0) { for(int i=0; i<10000; i++){ } money = money - 100; //取走100元 System.out.println("当前余额为" + balance +"元," + Thread.currentThread().getName() + "取走100元,还剩" + money + "元"); } }finally { lock.unlock(); } } @Override public void run(){ draw(); } }
再次运行main方法结果正确。 (当前余额为100元,wife取走100元,还剩0元)
二、
浙公网安备 33010602011771号