首页 > 其他分享 >多线程中的不同区域的变量的安全性问题测试

多线程中的不同区域的变量的安全性问题测试

时间:2023-09-05 18:32:44浏览次数:43  
标签:HasSelfPrivateNum 变量 numRef 安全性 num 线程 new 多线程 public

  1. 如果是方法中的变量,不存在线程安全问题。
  • 方法中的变量代码片段:
public class HasSelfPrivateNum {
    public void addI(String userName) {
	// 这里的num变量是存在于addI这个方法里面的
        int num = 0;
        try {
            if (userName.equals("a")) {
                num = 100;
                System.out.println(" a set over !");
                Thread.sleep(2000);
            } else {
                num = 200;
                System.out.println(" b set over !");
            }
            System.out.println(userName + " num = " + num);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

  • 线程a:
public class ThreadA extends Thread{
    private HasSelfPrivateNum numRef;
    public ThreadA(HasSelfPrivateNum numRef){
        super();
        this.numRef = numRef;
    }
    @Override
    public void run(){
        super.run();
        numRef.addI("a");
    }
}

  • 线程b:
public class ThreadB extends Thread {
    private HasSelfPrivateNum numRef;
    public ThreadB(HasSelfPrivateNum numRef) {
        super();
        this.numRef = numRef;
    }
    @Override
    public void run() {
        super.run();
        numRef.addI("b");
    }
}

  • 测试类:
public class Run {
    public static void main(String[] args) {
        HasSelfPrivateNum numRef = new HasSelfPrivateNum();
        ThreadA threadA = new ThreadA(numRef);
        threadA.start();
        ThreadB threadB = new ThreadB(numRef);
        threadB.start();
    }
}

  • 测试结果: image.png
  1. 再来测试一下,如果变量不是在方法中,而是在class中,结果如何?
  • 对象仅有一个实例变量,可能被覆盖
public class HasSelfPrivateNum {
    private int num = 0;
    public void addI(String userName) {
        try {
            if (userName.equals("a")) {
                num = 100;
                System.out.println(" a set over !");
                Thread.sleep(2000);
            } else {
                num = 200;
                System.out.println(" b set over !");
            }
            System.out.println(userName + " num = " + num);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

其余代码不变进行测试一下: image.png 这里可以看到测试的结果已经变了,a num也已经变成了200,解决的方法最直接的一种就是加上锁。通过再次测试加锁结果可以看到,已经能够保证线程安全,不会发生“脏读”读到其他线程修改结果的情况了。 image.png ==结论:两个线程先后访问同一个对象的同步方法是线程安全的!==

  1. 多个锁多个对象的情况 如果有多个对象的情况下,代码如下:
public class Run {
    public static void main(String[] args) {
        HasSelfPrivateNum numRef1 = new HasSelfPrivateNum();
        HasSelfPrivateNum numRef2= new HasSelfPrivateNum();
        ThreadA threadA = new ThreadA(numRef1);
        threadA.start();
        ThreadB threadB = new ThreadB(numRef2);
        threadB.start();
    }
}

测试结果如下: image.png ==结论:关键字synchronized取得的锁都是对象锁,而不是把一段代码或方法(函数)当作锁,所以在上面的示例中,哪个线程先执行带synchronized关键字的方法,哪个线程就持有该方法所属对象的锁Lock,那么其他线程只能呈等待状态,前提是多个线程访问的是同一个对象。但如果多个线程访问多个对象,则JVM会创建多个锁。上面的示例就是创建了2个HasSelfPrivateNum.java类的对象,所以就会产生出2个锁。==

  1. 继续测试验证
  • image.png
  • 如果是加上了锁,则会产生同步现象image.png ⚠️ 调用用关键字synchronized声明的方法一定是排队运行的。另外需要牢牢记住“共享”这两个字,只有共享资源的读写访问才需要同步化,如果不是共享资源,那么根本就没有同步的必要。
  1. image.png 结论:

1)A线程先持有object对象的Lock锁,B线程可以以异步的方式调用object对象中的非synchronized类型的方法。2)A线程先持有object对象的Lock锁,B线程如果在这时调用object对象中的synchronized类型的方法则需等待,也就是同步。

标签:HasSelfPrivateNum,变量,numRef,安全性,num,线程,new,多线程,public
From: https://blog.51cto.com/u_15927490/7378132

相关文章

  • Vite配置环境变量以及反向代理请求
    ❝我们在开发中会经常配置环境即ENV,并且在发送请求的时候会出现跨域问题,本文就着重讲一下Vite里面env的配置以及跨域的处理!❞envenv即环境,我们经常会配置开发环境、生产环境、测试环境。环境配置新建文件.env全环境.env.development开发环境.env.production生产环境.env.......
  • 《C++》11新特性--多线程
    thread创建线程,不会阻塞主线程thread成员函数voidthread::join();阻塞线程,当前线程执行完毕才会往下执行boolthread::joinble();线程是否可以连接,返回voidthread::detach();分离主线程和子线程的关联voidprintI(){for(size_ti=0;i<100;i++){std::c......
  • 多线程|生产者消费模型
    在正式介绍生产者消费者模型之前,我们先来认识一下阻塞队列。阻塞队列是特殊的队列,是在先进先出的基础上加了一些特殊的功能:1)如果队列为空,线程要执行出队操作时,就会进入阻塞,阻塞直到另一个线程往队列里添加元素;2)如果队列满了,线程要进行入队操作时,就会进入阻塞,直到有另一个线程从......
  • iOS代码加固与保护方法详解 - 提升iOS应用安全性的关键步骤
    摘要:作为一名从事iOS开发多年的技术博主,长期以来我都没有重视代码加密和加固。然而,最近了解到使用IPAGuard工具可以对iOS应用进行混淆保护,我开始重新审视iOS应用的安全性问题。本文将详细介绍如何使用IPAGuard工具进行代码加固和保护,以提高iOS应用的安全性和抵御逆向分析的风险。......
  • iOS代码加固与保护方法详解 - 提升iOS应用安全性的关键步骤
    摘要:作为一名从事iOS开发多年的技术博主,长期以来我都没有重视代码加密和加固。然而,最近了解到使用IPAGuard工具可以对iOS应用进行混淆保护,我开始重新审视iOS应用的安全性问题。本文将详细介绍如何使用IPAGuard工具进行代码加固和保护,以提高iOS应用的安全性和抵御逆向分析的风险......
  • ThreadLocal:线程中的全局变量 | 京东云技术团队
    最近接了一个新需求,业务场景上需要在原有基础上新增2个字段,接口新增参数意味着很多类和方法的逻辑都需要改变,需要先判断是否属于该业务场景,再做对应的逻辑。原本的打算是在入口处新增变量,在操作数据的时候进行逻辑判断将变量进行存储或查询。如果全链路都变更入参和结构,很明显代码......
  • ThreadLocal:线程中的全局变量
    最近接了一个新需求,业务场景上需要在原有基础上新增2个字段,接口新增参数意味着很多类和方法的逻辑都需要改变,需要先判断是否属于该业务场景,再做对应的逻辑。原本的打算是在入口处新增变量,在操作数据的时候进行逻辑判断将变量进行存储或查询。如果全链路都变更入参和结构,很明显代......
  • java多线程爬取笔趣阁所有小说
    可以选择下载的数量,全部下载下来够呛,首先没那么大的盘新版本:https://wws.lanzous.com/iAEMoghsgeb密码:7vjzjar包:https://wws.lanzous.com/ilphyghsgcj密码:f38a <dependency><!--jsoupHTMLparserlibrary[url=home.php?mod=space&uid=402414]@[/url]htt......
  • 多线程学习笔记
     1.进程和线程进程是指一个程序,例如QQ,打开会占用一定的内存和空间,会有产生和消亡。线程是由进程创造,一个进程可以有多个线程。单线程:在同一个时刻,只允许执行一个线程。多线程:在同一个时刻,允许执行多个线程。并发:同一时刻,多个任务交替执行,例如一台电脑同时运行qq和迅雷,看着貌似是有......
  • day02-变量
    1、变量的概念在我们生活中,提到一个人或者一个物体,会有一个名字来称呼它;那我们称呼一个人,我们不会叫一个人,而是喊他的名字,比如张三是这个人的名字 同样的,在计算机语言中,也是如此,我们会有很多数据或者对象,比如年龄18和名字张三那我们就需要存储这些数据或者对象,并且还要起个......