精华内容
下载资源
问答
  • Java变量线程安全分析
    千次阅读
    2022-01-21 16:23:42

    1.成员变量和静态变量

    • 如果他们没有共享,则是线程安全的

    • 如果他们被共享了:

      • 如果只有写操作,则线程安全
      • 如果存在读操作,并且这段代码在临界区,则需要考虑线程安全

    2.局部变量是否线程安全

    • 局部变量是线程安全的,因为不同线程访问局部变量均会在自己的方法栈中创建该方法的新的引用,互相之间不会产生干扰
    • 如果局部方法存在逃逸,当外部与局部方法变量存在引用关系,可能会由于多线程对该对象的更改导致线程安全问题
    更多相关内容
  • java多线程编程中,存在很多线程安全问题,至于什么线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同《java并发编程实践》中所说: 写道 给线程安全下定义比较困难。存在很多种定义,如:“一个类在可以被...

    (原文地址:http://blog.csdn.net/will_awoke/article/details/38044415

     

     

    java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同《java并发编程实践》中所说:

       写道

    给线程安全下定义比较困难。存在很多种定义,如:“一个类在可以被多个线程安全调用时就是线程安全的”。 

     此处不赘述了,首先给出静态变量、实例变量、局部变量在多线程环境下的线程安全问题结论,然后用示例验证,请大家擦亮眼睛,有错必究,否则误人子弟!

     

    静态成员变量线程非安全(无论单例或者非单例皆不安全)。

    静态变量即类变量,位于方法区,为所有对象共享,共享一份内存,一旦静态变量被修改,其他对象均对修改可见,故线程非安全。

     

     

    实例成员变量单例模式(只有一个对象实例singleton存在)线程非安全,非单例线程安全。

    实例变量为对象实例私有,在虚拟机的堆heap中分配,若在系统中只存在一个此对象的实例,在多线程环境下,“犹如”静态变量那样,被某个线程修改后,其他线程对修改均可见,故线程非安全(如,springmvc controller是单例的,非线程安全的);如果每个线程执行都是在不同的对象中,那对象与对象之间的实例变量的修改将互不影响,故线程安全(如,struts2 action默认是非单例的,每次请求在heap中new新的action实例,故struts2 action可以用实例成员变量)。

     

    局部变量线程安全(线程封闭性Thread Confinement)。

    每个线程执行时将会把局部变量放在各自栈帧的工作内存中,线程间不共享,故不存在线程安全问题。

     

    〖by self:上述所有的变量均指,共享的(Shared)和可变的(Mutable,进行了'read''write'操作)状态变量,只有对这样的变量讨论线程安全才有意义,所有实际上上述的“局部变量”一定是线程安全的,因为其不是共享的(Not Shared),至于非状态变量,毫无疑问,是线程安全的。〗

     

     

     

    一、静态成员变量 

     

    线程安全问题模拟:

    ----------------------------------------------------------------------------------

    [java] view plain copy

    1. /**   
    2.   * 线程安全问题模拟执行   
    3.   *  ------------------------------   
    4.   *       线程1      |    线程2   
    5.   *  ------------------------------   
    6.   *   static_i = 4;  | 等待   
    7.   *   static_i = 10; | 等待   
    8.   *    等待          | static_i = 4;   
    9.   *   static_i * 2;  | 等待   
    10.   *  -----------------------------  
    11.  * */    
    12. public class Test implements Runnable    
    13. {    
    14.     private static int static_i;//静态变量     
    15.         
    16.     public void run()    
    17.     {    
    18.         static_i = 4;    
    19.         System.out.println("[" + Thread.currentThread().getName()    
    20.                 + "]获取static_i 的值:" + static_i);    
    21.         static_i = 10;    
    22.         System.out.println("[" + Thread.currentThread().getName()    
    23.                 + "]获取static_i*2的值:" + static_i * 2);    
    24.     }    
    25.         
    26.     public static void main(String[] args)    
    27.     {    
    28.         Test t = new Test();    
    29.         //启动尽量多的线程才能很容易的模拟问题     
    30.         for (int i = 0; i < 3000; i++)    
    31.         {    
    32.             //t可以换成new Test(),保证每个线程都在不同的对象中执行,结果一样     
    33.             new Thread(t, "线程" + i).start();    
    34.         }    
    35.     }    
    36. }    

    根据代码注释中模拟的情况,当线程1执行了static_i = 4;  static_i = 10; 后,线程2获得执行权,static_i = 4; 然后当线程1获得执行权执行static_i * 2;  必然输出结果4*2=8,按照这个模拟,我们可能会在控制台看到输出为8的结果。

    写道

    [线程27]获取static_i 的值:4 
    [线程22]获取static_i*2的值:20 
    [线程28]获取static_i 的值:4 
    [线程23]获取static_i*2的值:8 
    [线程29]获取static_i 的值:4 
    [线程30]获取static_i 的值:4 
    [线程31]获取static_i 的值:4 
    [线程24]获取static_i*2的值:20

     看红色标注的部分,确实出现了我们的预想,同样也证明了我们的结论。

     

     

    二、实例成员变量

     

    线程安全问题模拟:

    ----------------------------------------------------------------------------------

    [java] view plain copy

    1. public class Test implements Runnable    
    2. {    
    3.     private int instance_i;//实例变量    
    4.         
    5.     public void run()    
    6.     {    
    7.         instance_i = 4;    
    8.         System.out.println("[" + Thread.currentThread().getName()    
    9.                 + "]获取instance_i 的值:" + instance_i);    
    10.         instance_i = 10;    
    11.         System.out.println("[" + Thread.currentThread().getName()    
    12.                 + "]获取instance_i*2的值:" + instance_i * 2);    
    13.     }    
    14.         
    15.     public static void main(String[] args)    
    16.     {    
    17.         Test t = new Test();    
    18.         //启动尽量多的线程才能很容易的模拟问题     
    19.         for (int i = 0; i < 3000; i++)    
    20.         {    
    21.             //每个线程对在对象t中运行,模拟单例情况    
    22.             new Thread(t, "线程" + i).start();    
    23.         }    
    24.     }    
    25. }    

    按照本文开头的分析,犹如静态变量那样,每个线程都在修改同一个对象的实例变量,肯定会出现线程安全问题。

    写道

    [线程66]获取instance_i 的值:10 
    [线程33]获取instance_i*2的值:20 
    [线程67]获取instance_i 的值:4 
    [线程34]获取instance_i*2的值:8 
    [线程35]获取instance_i*2的值:20 
    [线程68]获取instance_i 的值:4

     

    看红色字体,可知单例情况下,实例变量线程非安全。 

    将new Thread(t, "线程" + i).start();改成new Thread(new Test(), "线程" + i).start();模拟非单例情况,会发现不存在线程安全问题。

     

     

     三、局部变量

     

    线程安全问题模拟:

    ----------------------------------------------------------------------------------

    [java] view plain copy

    1. public class Test implements Runnable    
    2. {    
    3.     public void run()    
    4.     {    
    5.         int local_i = 4;    
    6.         System.out.println("[" + Thread.currentThread().getName()    
    7.                 + "]获取local_i 的值:" + local_i);    
    8.         local_i = 10;    
    9.         System.out.println("[" + Thread.currentThread().getName()    
    10.                 + "]获取local_i*2的值:" + local_i * 2);    
    11.     }    
    12.         
    13.     public static void main(String[] args)    
    14.     {    
    15.         Test t = new Test();    
    16.         //启动尽量多的线程才能很容易的模拟问题    
    17.         for (int i = 0; i < 3000; i++)    
    18.         {    
    19.             //每个线程对在对象t中运行,模拟单例情况     
    20.             new Thread(t, "线程" + i).start();    
    21.         }    
    22.     }    
    23. }    

    控制台没有出现异常数据。

     

     

    四、静态方法 是否是线程安全的:

    先看一个类

     

    [java] view plain copy

    1. public class  Test{  
    2. public static  String hello(String str){  
    3.     String tmp="";  
    4.     tmp  =  tmp+str;  
    5.    return tmp;  
    6. }  
    7. }  

     

     

    hello方法会不会有多线程安全问题呢?不会!

    静态方法如果没有使用静态变量,则没有线程安全问题。

    为什么呢?因为静态方法内声明的变量,每个线程调用时,都会新创建一份,而不会共用一个存储单元。比如这里的tmp,每个线程都会创建自己的一份,因此不会有线程安全问题。

     

    注意,静态成员变量,由于是在类加载时占用一个存储区,每个线程都是共用这个存储区的,所以如果在静态方法里使用了静态成员变量,这就会有线程安全问题。即只要方法内含有静态成员变量,就是非线程安全的,(实际上归根到底还是变量的线程安全问题~)。

    展开全文
  • 在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
  • 成员变量线程安全

    2015-12-01 17:13:00
    通过集中情况来观察成员变量线程安全的影响: 1.数据共享 线程类代码如下: package com.feng.example; public class MyThread extends Thread { private int count = 5; @Override ...

    通过集中情况来观察成员变量对线程安全的影响:

    1.数据不共享

    线程类代码如下:

    package com.feng.example;
    
    public class MyThread extends Thread {
    
    	private int count = 5;
    	
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		while(count > 0)
    		{
    			count--;
    			System.out.println(Thread.currentThread().getName()+"==="+count);
    		}
    	}	
    }

    测试类代码如下

    package com.feng.example;
    
    public class ThreadTest {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		
    		Thread a = new MyThread();
    		Thread b = new MyThread();
    		Thread c = new MyThread();
    
    		a.start();
    		b.start();
    		c.start();
    	}
    
    }

    分析:在主程序中分别创建了三个线程实例对象,三个实例对象有自己的内容空间,有自己的成员变量,内存模型如下图所示:

    155154_CvJ5_2309504.jpg

    三个线程a.b.c都有各自的count成员变量,三者运行互不影响。因此在数据不共享的情况下是不会出现线程安全问题的。

    程序输出:

    Thread-0===4
    Thread-0===3
    Thread-0===2
    Thread-0===1
    Thread-0===0
    Thread-1===4
    Thread-1===3
    Thread-1===2
    Thread-1===1
    Thread-1===0
    Thread-2===4
    Thread-2===3
    Thread-2===2
    Thread-2===1
    Thread-2===0

    2.数据共享

    在数据共享这一部分分为两个部分来讲:

    (1)多个线程实例(同一个类的实例)的成员变量指向同一个对象,那就将成员变量改为static类型

    线程类改写为:

    package com.feng.example;
    
    public class MyThread extends Thread {
    
    	private static int  count = 5;
    	
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		while(count > 0)
    		{
    			count--;
    			System.out.println(Thread.currentThread().getName()+"==="+count);
    		}
    	}	
    }

    测试类不变:

    分析:三个实例对象的成员变量都是使用指向的同一个成员变量,内存结构如下图所示:

    161621_YwL4_2309504.jpg

    三个线程修改的是同一个count变量,那么执行结果就不再是每一个线程都会循环5次了。除此之外,当线程a执行到了count--时,cpu切换去执行线程b,线程同样执行到count--然后输出,就会出现输出两次3,而没有结果4。这就出现了线程安全问题。其他的线程修改了本线程中还未处理完的数据(这里指的是输出)。

    输出结果为:

    Thread-0===3
    Thread-0===2
    Thread-0===1
    Thread-0===0
    Thread-1===3

    由结果可以看出,Thread-0和Thread-1都输出了3,而正确的结果应该是输出4,3,2,1,0这几个数组都有的

    解决方案:可以将方法定义为同步方法,在方法前加synchronized关键字??这种解决当然不正确,因为三个线程实例是三个对象,方法级别的synchronized是对对象加锁,所以对象各不相同因此在方法上加同步是没有任何效果的。正确的做法是使用synchronized语句块对MyThread的class文件加锁,程序修改如下:

    package com.feng.example;
    
    public class MyThread extends Thread {
    
    	private static int  count = 5;
    	
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		synchronized(MyThread.class)
    		{
    			while(count > 0)
    			{
    				count--;
    				System.out.println(Thread.currentThread().getName()+"==="+count);
    			}
    		}
    	}	
    }

    测试类不修改,执行结果如下:

    Thread-2===4
    Thread-2===3
    Thread-2===2
    Thread-2===1
    Thread-2===0

    当然解决的方案有很多,这里不细讲解决方案。

    有的书本中的讲解都会提及count++, count--会被分成三步操作的问题,这里我个人认为存在这一方面的原因,但也存在count--后时间片到了的情况,去执行其他线程的代码块,导致了count的值不准确。验证这一说法的办法就是将count--修改为--count,--count课时寄存器自减操作不会分成三步操作了吧。结果同样会出现相同的值。这个验证大家自行测试。

    (2)不同的线程(不同的线程类)引用同一对象作为成员变量

    定义两个线程MyThreadA,MyThreadB,自定义类MyNum用于计数

    package com.feng.example;
    
    public class MyNum {
    	
    	int count;
    
    	public int getCount() {
    		return count;
    	}
    
    	public void setCount(int count) {
    		this.count = count;
    	}
    }
    package com.feng.example;
    
    public class MyThreadA extends Thread{
    
    	private MyNum count;
    	
    	public MyThreadA(MyNum count)
    	{
    		this.count = count;
    	}
    	
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		while(count.getCount()  >0)
    		{
    			count.setCount(count.getCount()-1);
    			System.out.println(Thread.currentThread().getName()+"====="+count.getCount());
    		}
    	}
    
    	
    }
    package com.feng.example;
    
    public class MyThreadB extends Thread{
    
    	private MyNum count;
    	
    	public MyThreadB(MyNum count)
    	{
    		this.count = count;
    	}
    	
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		while(count.getCount()  >0)
    		{
    			count.setCount(count.getCount()-1);
    			System.out.println(Thread.currentThread().getName()+"====="+count.getCount());
    		}
    	}
    
    	
    }

    测试类:

    package com.feng.example;
    
    public class ThreadTest {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		
    		MyNum count = new MyNum();
    		count.setCount(5);
    		Thread a = new MyThreadA(count);
    		Thread b = new MyThreadB(count);
    
    		a.start();
    		b.start();
    	}
    
    }

    通过传递同一个对象给两个线程,这两个线程共用这一个计数器。因为没有同步操作,这个线程执行还会出现线程安全问题。

    输出结果:

    Thread-1=====3
    Thread-0=====3
    Thread-1=====2
    Thread-0=====1
    Thread-1=====0

    解决方案:可以使用LocalThread解决,也可以使用sychronized解决,此处不细讲。

    如果此处将计数器简单的使用Integer类型,观察会有什么不同?为什么?

    通过以上实验可以得出,不管是同一个class文件产生的多个线程实例还是多个class文件产生的多个线程实例,只要对同一个对象进行处理就会出现线程安全问题。

    3.浅谈web中的Servlet

    Servlet是单例的,意思就是说不管多少个请求,如果请求的是同一个Servlet,那么他们都会使用同一个Servlet对象。

    如果不慎在Servlet中使用成员变量保存前台传输过来的数据,那么后台数据将会产生错乱(为什么?查看共享数据中的第二个例子,将MyNum想象成Servlet,使用count接收前台的数据)。因此在Servlet中都是在doGet或者doPost方法中使用局部变量来接收前台的数据,因为每次调用方法时,都会为此次方法调用开辟空间,方法中的各个局部变量之间没有影响。

    因此在Servlet中很少使用成员变量。我将单独列出一个模块讨论多线程和单例之间的关系,这里就不深入研究了。

    用自己的话总结一下:线程安全问题就是指应该成为原子操作的模块没有完整的执行。


    转载于:https://my.oschina.net/u/2309504/blog/537944

    展开全文
  • 子类用父类成员变量线程安全问题

    千次阅读 2019-12-03 13:54:19
    假设现在有一个父类Father,它里面的变量需要占用1M内存.有一个它的子类Son,它里面的变量需要占用0.5M内存. 现在通过代码来看看内存的分配情况: Fatherf=newFather();//系统将分配1M内存. Sons=newSon();//系统将...

    Java父类与子类的 内存引用讲解

    从对象的内存角度来理解试试.
    假设现在有一个父类Father,它里面的变量需要占用1M内存.有一个它的子类Son,它里面的变量需要占用0.5M内存.
    现在通过代码来看看内存的分配情况:
    Father f = new Father();//系统将分配1M内存.

    Son s = new Son();//系统将分配1.5M内存!因为子类中有一个隐藏的引用super会指向父类实例,所以在实例化子类之前会先实例化一个父类,也就是说会先执行父类的构造函数.由于s中包含了父类的实例,所以s可以调用父类的方法.

    Son s1 = s;//s1指向那1.5M的内存.

    Father f1 = (Father)s;//这时f1会指向那1.5M内存中的1M内存,即是说,f1只是指向了s中实例的父类实例对象,所以f1只能调用父类的方法(存储在1M内存中),而不能调用子类的方法(存储在0.5M内存中).

    Son s2 = (Son)f;//这句代码运行时会报ClassCastException.因为f中只有1M内存,而子类的引用都必须要有1.5M的内存,所以无法转换.

    Son s3 = (Son)f1;//这句可以通过运行,这时s3指向那1.5M的内存.由于f1是由s转换过来的,所以它是有1.5M的内存的,只是它指向的只有1M内存.

    前提是:每个子类都实例化对象,即多例情况(非单例)

    每一个子类都实例化了,其父类也会随之使例化,接着子类再实例化,父类、子类里面的属性字段都是独立的,所以处于公用部分的其父类中的成员变量 就相当于是线程安全的

    package abstracts;
    
    public abstract class B {
        /**
         * 子类实例化后,父类也被实例化,所以在子类多例的情况下,父类中的成员变量:
         * private String str 是线程安全的
         */
        private String str;
    
        public B() {
            System.out.println("父类已经实例化");
        }
    
        public B(String a) {
            this.str = a;
            System.out.println(str);
        }
    
        public abstract void play();
    }  
    package abstracts;
    
    public class C extends B {
    
        public C(String c) {
            super(c);
            System.out.println("子类已经被实例化");
        }
    
        @Override
        public void play() {
            System.out.println("我实现了父类的方法");
        }
    
        public static void main(String[] args) {
            B c = new C("c");
            B c1 = new C("b");
        }
    
    
    }  

    打印结果:

    c
    子类已经被实例化
    b
    子类已经被实例化
    

     

    展开全文
  • public class Test{ ...如上代码片段中有一个实例变量,如果在一个多线程高并发的场景下运行,会存在线程安全问题吗?答案是非常有可能。 #mermaid-svg-NQNIAGNu4RCj2E6k .label{font-family:'trebuchet ms'
  • 产生线程安全问题的原因:静态变量即类变量,只初始化一次,位于方法区,所有对象共享,共享一份内存,一旦静态变量被修改,其他对象均对修改可见,故线程非安全。 静态变量多线程操作示例: 根据上图代码可知,...
  • 为什么StringBuilder是线程不安全的?

    万次阅读 多人点赞 2020-09-17 17:58:21
    在前面的面试题讲解中我们对比了String、StringBuilder和StringBuffer的区别,其中一项便提到StringBuilder是非线程安全的,那么是什么原因导致了StringBuilder的线程安全呢? 原因分析 如果你看了StringBuilder或...
  • 经常会看到说HashMap是线程安全的,ConcurrentHashMap是线程安全的等等说法,不禁有个疑问,什么线程安全什么样的类是线程安全的? 1.什么线程安全性(what) 线程安全定义,最核心是正确性, 正确性:多...
  • 这两种变量引起线程安全问题的原因和区别如下:1、静态变量静态变量即静态成员变量。只要有修改变量值的操作,无论是在单例或者非单例都是线程安全的;而如果线程只是读取变量的值,而不会改变变量的值,这种情况...
  • C++ static 变量线程安全和单例模式

    千次阅读 2021-11-23 14:10:54
    1.1 全局变量、文件域的static变量和类的static成员变量在main函数执行之前初始化 1.2 局部静态变量在第一次被使用时初始化 static变量的线程安全 2.1 非局部静态变量是线程安全的 2.2 局部静态变量在C++11后也是...
  • 为什么StringBuilder是线程不安全

    千次阅读 2019-08-30 14:40:12
    通常我们都知道说StringBuilder是线程不安全的,那如果继续追问下去,为什么StringBuilder是线程不安全的,该怎么回答呢? 首先需要明确地知道StringBuilder它内部的组织结构 来看源代码中,StringBuilder的抽象...
  • 在Spring中,注解@Controller去修饰一个类时,默认这个类是单例。但是WEB容器为了性能,必然是多线程的去...所以在单例的Controller类中,如果存在全局变量,必然会存在线程安全问题。 下面将示范多种常用写法,有...
  • // 单例的名字,可以通过修改该成员变量,判断单例是否真的只有一个,本例子没做这部分内容判断,感兴趣可以自己改一下这个名字后,输出一下 private static SingleClass self;// 持有自身对象的引用 private Sing
  • 局部变量线程安全问题

    千次阅读 2018-01-10 15:49:22
    局部变量线程安全问题 只看楼主 收藏 回复 mincike 沝 2 求大神给解释下 回复 1楼 2016-02-...
  • 1.Qt下,多线程使用互斥锁安全访问同一全局变量;2.源码中定义了ThreadA和ThreadB,定义变量后,依次调用函数start()来启动重写的run()函数
  • final 静态变量线程安全

    千次阅读 2019-01-08 16:30:44
    我的代码中已经多次使用了线程,然后还非常喜欢使用据说是线程安全的静态方法,然后又看到很多地方最容易提的问题就是这个东西线程安全   于是我不免产生了以下几个... 什么是快速把一段代码变成线程安全的...
  • java 成员变量线程安全

    千次阅读 2010-03-26 13:49:00
    本文讲解的是关于java成员变量线程安全问题,包括静态变量和实例变量。静态变量好理解,所有实例都共享一份内存,任何对静态变量的修改都会引发线程安全问题。然而,对于实例变量,在大多数情况下的访问和修改都是...
  • Spring中的线程安全

    千次阅读 2022-01-27 16:11:45
    spring线程安全
  • StringBuilder为什么线程不安全

    万次阅读 多人点赞 2019-08-30 10:08:24
    作者:千山 juejin.im/post/5d6228046fb...我:StringBuilder不是线程安全的,StringBuffer是线程安全的 面试官:那StringBuilder安全的点在哪儿? 我:。。。(哑巴了) 在这之前我只记住了StringBuilder不是...
  • c++11 静态成员线程安全

    千次阅读 2018-08-21 21:52:00
    c++11 要求保证函数内部静态变量线程安全。 实测是保证静态成员构造的时候线程安全。 #include &lt;iostream&gt; #include &lt;unistd.h&gt; #include &lt;pthread.h&gt; using ...
  • StringBuilder为什么线程不安全

    千次阅读 2019-08-26 10:06:50
    我:StringBuilder不是线程安全的,StringBuffer是线程安全的 面试官:那StringBuilder安全的点在哪儿? 我:。。。(哑巴了) 在这之前我只记住了StringBuilder不是线程安全的,StringBuffer是线程安全的这个...
  • 浅析Java各种变量线程安全问题

    千次阅读 2019-04-30 11:45:47
    与静态成员变量一样,属于类本身,在类装载的时候被装载到内存(Memory),自动进行销毁,会一直存在于内存中,直到JVM关闭。 非静态方法(Non-Static Method) 又叫实例化方法,属于实例对象,实例化后才会分配...
  • 变量线程安全分析

    千次阅读 2022-02-21 15:12:25
    成员变量和静态变量是否线程安全? 如果它们没有共享,则线程安全。 如果它们被共享了,根据他们的状态是否能够改变,...局部变量线程安全分析 想一想,这段代码被多个线程访问,它是线程安全的吗? public stati
  • 有时候,对于在多线程中使用static变量有没有冲突,是否存在安全问题能十分的确定。在使用过程中有点含糊,总想找点时间好好追究一下,可总因开发项目时间的紧迫而搁浅。我想,没有做进一步的研究而拿项目繁忙说事...
  • ThreadLocal是JDK提供的,支持线程本地变量。也就是说,如果我们创建了一个ThreadLocal变量,则...如果多个线程同时对这个变量进行读写操作时,实际上操作的是线程自己本地内存中的变量,从而避免了线程安全的问题。
  • //这里定义一个boolean变量 String name; int age; } public class GetStudent implements Runnable{ private Student s; public GetStudent(Student s){ this.s = s; } @Override public void run() { ...
  • C++11静态变量构造线程安全

    千次阅读 2020-08-07 14:13:13
    在c++11中,static静态类对象在执行构造函数进行初始化的过程是线程安全的。 #include #include using namespace std; class Cnum { public: Cnum() { std::cout << “construct start” << std::endl...
  • 那么我们想着如果保证线程安全可以使用原子操作,比如CAS机制、synchronized,我们知道CAS原子操作只能一个引用或者对象实例源自操作,那么上述两句代码就可以使用synchronized。 4、WHY synchronized为什么可以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 164,124
精华内容 65,649
关键字:

为什么成员变量线程不安全

友情链接: cd4ef1.ZIP