java多线程三种上锁方式小结

 更新时间:2023年12月22日 11:06:16   作者:湖边看客  
本文主要介绍了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();

    }

}

效果: 

到此这篇关于java多线程三种上锁方式小结的文章就介绍到这了,更多相关java多线程上锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • Java异步编程的5种异步实现方式详解

    Java异步编程的5种异步实现方式详解

    这篇文章主要介绍了Java异步编程的5种异步实现方式详解,异步编程是程序并发运行的一种手段,它允许多个事件同时发生,当程序调用需要长时间运行的方法时,它不会阻塞当前的执行流程,程序可以继续运行,需要的朋友可以参考下
    2024-01-01
  • 详细总结各种排序算法(Java实现)

    详细总结各种排序算法(Java实现)

    下面小编就为大家带来一篇详细总结各种排序算法(Java实现)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • Quarkus篇入门创建项目搭建debug环境

    Quarkus篇入门创建项目搭建debug环境

    这篇文章主要为大家介绍了Quarkus篇入门创建项目搭建debug环境,先来一套hello world,来搭建基本的运行及调试环境吧
    2022-02-02
  • Java写哈希表的完整实例代码

    Java写哈希表的完整实例代码

    Java中的哈希表是数据结构中的一个重要组成部分,用于高效存储和查找数据,这篇文章主要介绍了Java写哈希表的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2026-03-03
  • Java实现将二叉树展开为链表的两种方法

    Java实现将二叉树展开为链表的两种方法

    文章介绍了两种方法将二叉树按前序遍历顺序展开为单链表,方法一为迭代法,方法二为前序遍历+列表重建,两者各有优缺点,选择时需根据实际需求和场景考虑,下面小编给大家详细说说
    2025-05-05
  • 深入理解MyBatis中的一级缓存与二级缓存

    深入理解MyBatis中的一级缓存与二级缓存

    这篇文章主要给大家深入的介绍了关于MyBatis中一级缓存与二级缓存的相关资料,文中详细介绍MyBatis中一级缓存与二级缓存的工作原理及使用,对大家具有一定的参考性学习价值,需要的朋友们下面来一起看看吧。
    2017-06-06
  • JDK动态代理原理:只能代理接口,不能代理类问题

    JDK动态代理原理:只能代理接口,不能代理类问题

    这篇文章主要介绍了JDK动态代理原理:只能代理接口,不能代理类问题。具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • @Scheduled注解的scheduler属性作用及说明

    @Scheduled注解的scheduler属性作用及说明

    @Scheduled注解用于定义周期性任务,其scheduler属性允许指定自定义Scheduler,以实现更灵活的调度控制,可共享资源、满足复杂需求,或使用默认ThreadPoolTaskScheduler,通过配置SchedulerBean并注入,确保调度器一致性和灵活性
    2026-04-04
  • maven中profile动态打包不同环境配置文件的实现

    maven中profile动态打包不同环境配置文件的实现

    开发项目时会遇到这个问题:开发环境,测试环境,生产环境的配置文件不同, 打包时经常要手动更改配置文件,本文就来介绍一下maven中profile动态打包不同环境配置文件的实现,感兴趣的可以了解一下
    2023-10-10
  • java中javamail发送带附件的邮件实现方法

    java中javamail发送带附件的邮件实现方法

    这篇文章主要介绍了java中javamail发送带附件的邮件实现方法,较为详细的分析了JavaMail发送邮件的用法,是非常实用的技巧,需要的朋友可以参考下
    2015-01-01

最新评论