java多线程三种上锁方式

以下以两人共用一个银行卡账户的方式,同时取钱,两条线程同时执行,为了保证线程安全,我们对关键的部分进行加锁的三种方式

线程类

public class DrawThread extends Thread {
    private Account acc;

    public DrawThread(Account acc, String name){
        super(name);
        this.acc=acc;
    }

    @Override
    public  void run(){
        //取钱  //每个线程在start的时候   都会执行  这个run方法
        acc.drawMoney(10000);
    }
}

账户类

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Account {
    private  String cardId;
    private  double money;
    //创建一个锁对象
    private final Lock lk =new ReentrantLock(); //手动锁


    public Account() {
    }

    public Account(String cardId, double money) {
        this.cardId = cardId;
        this.money = money;
    }


    //静态代码   用class作为锁
    public static  void test(){
        synchronized (Account.class){

        }
    }

    //取钱的方法
    //同步代码块上锁
     /**   public void drawMoney(double money){
            //谁来取钱?
            String name = Thread.currentThread().getName();
            //判断余额是否足够
            synchronized (this){  //this 在这个过程中是共同拥有的相同的数据 所以能锁住
                if(this.money>=money){
                    System.out.println(name+"取钱"+money+"成功!");
                    this.money -= money;
                    System.out.println(name+"取钱后,剩余"+this.money);
                }else {
                    System.out.println(name+"余额不足");
                }
            }
        }
    */

    //取钱方法
    //同步方法上锁
    /** public synchronized void drawMoney(double money){
         //谁来取钱?
         String name = Thread.currentThread().getName();
         //判断余额是否足够
             if(this.money>=money){
                 System.out.println(name+"取钱"+money+"成功!");
                 this.money -= money;
                 System.out.println(name+"取钱后,剩余"+this.money);
             }else {
                 System.out.println(name+"余额不足");
             }

     }
    */

    //取钱的方法
    //手动锁
    public synchronized void drawMoney(double money){
        //谁来取钱?
        String name = Thread.currentThread().getName();
        lk.lock(); //加锁
        //判断余额是否足够
        if(this.money>=money){
            System.out.println(name+"取钱"+money+"成功!");
            this.money -= money;
            System.out.println(name+"取钱后,剩余"+this.money);
        }else {
            System.out.println(name+"余额不足");
        }
        lk.unlock(); //解锁
    }




    public String getCardId() {
        return cardId;
    }

    public void setCardId(String cardId) {
        this.cardId = cardId;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

}

执行

public class ThreadTest {

    public static void main(String[] args) {
        //创建一个账户
        Account acc = new Account("ic000",10000);
        //创建两个线程分别代表小明和小红  同时  在这个个账户中取钱


        new DrawThread(acc,"小明").start();

        new DrawThread(acc,"小红").start();


        Account acc2 = new Account("ic002",10000);
        //创建两个线程分别代表小明和小红  同时  在这个个账户中取钱

        new DrawThread(acc2,"小黑").start();

        new DrawThread(acc2,"小白").start();

    }

}

效果: 

  • 24
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值