首页 > 其他分享 >多线程:线程安全

多线程:线程安全

时间:2024-09-06 15:52:59浏览次数:7  
标签:name money System 安全 线程 println 多线程 public out

线程安全

多个线程,同时操作同一个共享资源的时候,可能会出现安全问题。

例如:两个人来取钱的案例

 

public class test {
    public static void main(String[] args) {
        // 1. 创建一个账户对象。代表账户人的共享账户。
        Account acc = new Account( "ICBC-110",  100000);
        // 2. 创建两个线程,代表两个代理同时操作该账户,一会取100,一会取200。
        new DrawThread(acc, "小明").start(); // 小明
        new DrawThread(acc, "小红").start(); // 小红
    }
}

线程启动

public class DrawThread extends Thread {
    private Account acc;
    public DrawThread(Account acc, String name) {
        super(name);
        this.acc = acc;
    }
    @Override
    public void run() {
        acc.drawMoney(100000);

    }
}

取钱账号及构造器

public class Account {
    private String cardId;
    private double money;

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

// 小明和小红可以过来
public void drawMoney(double money) {
    // 先知道是谁来取钱
    String name = Thread.currentThread().getName();
    // 1. 判断账户当前余额是否足够
    if (this.money >= money) {
        System.out.println(name + "来取钱成功,吐出:" + money);
        this.money -= money;
        System.out.println(name + "来取钱后,余额剩余:" + this.money);
    } else {
        System.out.println(name + "来取钱,余额不足!");
    }
}

public String getCardId() { return cardId; }
public void setCardId(String cardId) { this.cardId = cardId; }
public double getMoney() { return money; }

}

线程同步

目的:解决线程安全问题。

思想:让多个线程先后一次访问共享资源,这样就解决了安全问题。

常见方案:

加锁

每次只允许一个线程加锁,加锁后才能进入访问,访问完毕后自动解锁,然后其他线程才能加锁进来。

方法一、同步代码块(synchronized)

把访问共享资源的核心代码给上锁,以此保证线程安全。

this只会影响同一个账户下的用户,不会影响不同用户的账户。

synchronized ("lock") {
    if (this.money >= money) {
        System.out.println(name + "来取钱成功,吐出:" + money);
        this.money -= money;
        System.out.println(name + "来取钱后,余额剩余:" + this.money);
    } else {
        System.out.println(name + "来取钱,余额不足!");
    }
}

ctrl alt t  就可以上锁。

对于静态对象来说

synchronized ("lock") {
    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();
    // 1. 判断账户当前余额是否足够
   
        if (this.money >= money) {
            System.out.println(name + "来取钱成功,吐出:" + money);
            this.money -= money;
            System.out.println(name + "来取钱后,余额剩余:" + this.money);
        } else {
            System.out.println(name + "来取钱,余额不足!");
        }
    
}

底层原理;

同步方法其实也是有隐式锁对象的,只是所得范围是整个方法代码。

如果方法是实例方法,同步方法默认使用this作为锁对象。

如果是静态方法:同步方法默认使用类名.class作为的锁对象。

同步代码块月同步方法比较:

同步代码块锁的范围更小,大家都可以先加载方法,再执行没有被锁的代码,最后分批执行被锁代码,所以效率更高。

方法三、Lock锁

程序员手动上锁,通过他可以创建出锁对象进行加锁和解锁,更强大、灵活、方便。

Lock是接口,不能实例化,要使用他的实现类ReentrantLock来创建Lock锁对象。

public class Account {
    private String cardId;
    private double money;
    private final Lock lk = new ReentrantLock();
public Account(String cardId, double money) {
    this.cardId = cardId;
    this.money = money;
}

//public static void test(){
//    synchronized (Account.class){
//
//    }
//}
// 小明和小红可以过来
public void drawMoney(double money) {
    // 先知道是谁来取钱
    String name = Thread.currentThread().getName();
    // 1. 判断账户当前余额是否足够
    try {
        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 + "来取钱,余额不足!");
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    } finally {//防止出现错误,一直被锁

        lk.unlock();
    }

}

标签:name,money,System,安全,线程,println,多线程,public,out
From: https://blog.51cto.com/u_16382144/11938432

相关文章

  • 一个网络安全情报聚合网站《魔盒安全情报》
    《魔盒》一款专为网络安全领域提供服务的多端情报系统。实时更新安全情报。内容包括威胁情报、数据泄露、漏洞预警、军事情报、安全博客情报等。地址网页端:https://mgb.abyssdawn.com/APP下载:https://mgb-app.abyssdawn.com/tg推送频道频道地址:https://t.me/mgb_sec_th......
  • 【Linux修行路】线程安全和死锁
    目录⛳️推荐一、线程安全1.1常见的线程不安全情况1.2常见的线程安全情况1.3常见的不可重入情况1.4常见可重入的情况1.5可重入与线程安全的联系1.6可重入与线程安全的区别二、死锁2.1死锁的四个必要条件2.2如何避免产生死锁?⛳️推荐前些天发现了一个巨牛......
  • 网络安全等级保护测评:等保一体机
       等保一体机,即“等级保护一体机”,是符合中国网络安全等级保护要求的一种设备。等级保护制度是中国政府为了加强信息系统安全管理,确保信息系统的安全性和稳定性,提出的一项措施。等保一体机旨在通过集成多种安全功能,为信息系统提供全面的保护。   等级保护制度分......
  • python语言基础(七)--多进程多线程
    多进程,多线程1、多任务概述多个任务同时执行目的节约资源,充分利用CPU资源,提高效率表现形式并发:针对于单核CPU来讲的,如果有多个任务同时请求执行,但是同一瞬间CPU只能执行1个(任务),于是就安排它们交替执行.因为时间间隔非常短(CPU执行速度太快......
  • 基于ssm+vue校园疫情安全管理系统设计与实现【开题+程序+论文】
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着全球新冠疫情的持续影响,校园作为人群密集、交流频繁的场所,其疫情防控工作显得尤为重要。传统的人工管理方式在应对大规模学生及教职工的健康监测......
  • 非常值得一看,最低月薪上万的运维安全工程师学习路线_运维学习路线_运维开发学习路线
    ......
  • ros 多线程模式
    ros::spin()的作用在ROS中,ros::spin()的主要作用是:让ROS节点持续运行,并处理所有注册的回调函数。在内部,它不断地检查ROS网络中的消息、服务请求,并调用相应的回调函数来处理它们。内部原理事件循环(EventLoop):ros::spin()进入一个事件循环。这个循环不断地......
  • 中国科学院信息工程研究所招聘网络安全专业
    给大家的福利......
  • 多线程
    线程(Thread)概述线程是一个程序内部的一条执行流程。多线程指的是从软硬件上实现的多条执行流程的技术(多条线程由CPU负责调度执行)。多线程的创建方式1.继承Thread。重写run方法,在run中执行每次执行结果都会不一样publicclassThreadTest1{//main方法是一条或多条线程负责执......
  • 亚信安慧AntDB数据库与华为DPA数据保护一体机完成兼容性互认证,共筑数据安全与效率新高
    近日,湖南亚信安慧科技有限公司(简称“亚信安慧”)与华为技术有限公司(简称“华为”)完成了亚信安慧AntDB数据库与华为DPA数据保护一体机兼容性互认证。图:华为DPA数据保护一体机兼容性互认证亚信安慧AntDB数据库作为领先的数据库解决方案提供商,专注于数据库产品的研发与创新,以其卓越......