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元)

 

二、

 

posted on 2019-05-05 20:22  有点懒惰的大青年  阅读(541)  评论(0)    收藏  举报