再次理解多线程线程安全问题(理解java内存模型后)

1.多线程访问的共享资源存在线程安全问题,

无外乎访问两种共享资源。

1)多线程访问方法区数据。存在线程安全问题,通过加锁

2)多线程访问实例变量:被访问对象是单例时存在线程安全,被访问对象是多例时,是线程安全的。

来说说静态变量、实例变量、局部变量在多线程下的安全问题吧!

(一)验证静态变量的线程安全性:

(1)从程序执行的图中我们可以看出,执行结果中有错误数据,证明了静态变量是存在资源冲突问题的。

(2)程序运行结果图:

5、结论:静态变量也称为类变量,属于类对象所有,位于方法区,为所有对象共享,共享一份内存,一旦值被修改,则其他对象均对修改可见,故线程非安全。

(二)实例变量:单例时线程非安全,非单例时线程安全

1、实例变量:实例变量属于类对象的,也就是说,属于对象实例私有,在虚拟机的堆中分配。

2、验证实例变量的线程安全性:

(1)从程序截图中,我们可以看到,当为单例模式时,会产生资源冲突,当非单例模式时,则不会产生线程冲突。

(2)程序运行结果图:

图1:

图2:

3、结论:实例变量是实例对象私有的,系统只存在一个实例对象,则在多线程环境下,如果值改变后,则其它对象均可见,故线程非安全;如果每个线程都在不同的实例对象中执行,

则对象与对象间的修改互不影响,故线程安全。

(三)局部变量:线程安全

1、局部变量:定义在方法内部的变量。

2、验证局部变量的安全性:

(1)从程序截图中可以看出,局部变量在多线程下没有产生资源冲突的问题

(2)程序运行结果图:

3、结论:每个线程执行时都会把局部变量放在各自的帧栈的内存空间中,线程间不共享,故不存在线程安全问题。

本文参考http://longw.blog.51cto.com/6475045/1683360,感谢原作者

时间: 2024-10-10 11:50:26

再次理解多线程线程安全问题(理解java内存模型后)的相关文章

(Java多线程系列七)Java内存模型和线程的三大特性

Java内存模型和线程的三大特性 多线程有三大特性:原子性.可见性.有序性 1.Java内存模型 Java内存模型(Java Memory Model ,JMM),决定一个线程对共享变量的写入时,能对另一个线程可见.从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本.本地内存是JMM的一个抽象概念,并不真实存在. 用一张图表示

全面理解Java内存模型(JMM)及volatile关键字(转)

原文地址:全面理解Java内存模型(JMM)及volatile关键字 关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入理解Java并发之synchronized实现原理 Java并发编程-无锁CAS与Unsafe类及其并发包Atomic 深入理解Java内存模型(JMM)及volatile关键字 剖析基于并发AQS的重入锁(Reetr

jvm(12)-java内存模型与线程

[0]README 0.1)本文部分文字描述转自“深入理解jvm”,旨在学习“java内存模型与线程” 的基础知识: [1]概述 1)并发处理的广泛应用是使得 Amdahl 定律代替摩尔定律称为计算机性能发展源动力的根本原因: 2)Amdahl 定律:该定律通过系统中并行化与串行化的比重来描述多处理器系统能获得的运算加速能力: 3)摩尔定律:该定律用于描述处理器晶体管数量与运行效率间的发展关系: Conclusion)这两个定律的更替代表了近年来硬件发展从追求处理器频率到追求多核心并行处理的发展

Java内存模型之总结

经过四篇博客阐述,我相信各位对Java内存模型有了最基本认识了,下面LZ就做一个比较简单的总结. 总结 JMM规定了线程的工作内存和主内存的交互关系,以及线程之间的可见性和程序的执行顺序.一方面,要为程序员提供足够强的内存可见性保证:另一方面,对编译器和处理器的限制要尽可能地放松.JMM对程序员屏蔽了CPU以及OS内存的使用问题,能够使程序在不同的CPU和OS内存上都能够达到预期的效果. Java采用内存共享的模式来实现线程之间的通信.编译器和处理器可以对程序进行重排序优化处理,但是需要遵守一些

Java内存模型与线程 深入理解Java虚拟机总结

在许多情况下,让计算机同时去做几件事情,不仅是因为计算机的运算能力强大了,还有一个很重要的原因是计算机的运算速度与它的存储和通信子系统速度的差距太大, 大量的时间都花费在磁盘I/O.网络通信或者数据库访问上. 如果不希望处理器在大部分时间里都处于等待其他资源的状态,就必须使用一些手段去把处理器的运算能力 " 压榨 " 出来, 否则就会造成很大的浪费,而计算机同时处理几项任务则是最容易想到.也被证明是非常有效的 " 压榨 " 手段. 除了充分利用计算机处理器的能力外,

深入理解Java虚拟机- 学习笔记 - Java内存模型与线程

除了在硬件上增加告诉缓存之外,为了使得处理器内部的运算单元能尽量被充分利用,处理器可能会对输入代码进行乱序执行(Out-Of-Order Execution)优化,处理器会在计算之后将乱序执行的结果重组,保证该结果与顺序执行的结果一致,但并不保证程序中各个语句计算的先后顺序与输入代码中的顺序一致,因此,如果存在一个计算任务依赖另外一个计算任务的中间结果,那么其顺序性并不能靠代码的先后顺序来保证.与处理器的乱序优化执行类似,Java虚拟机的即时编译器中也有类似的指令重排序(Instruction

深入理解java虚拟机-第12章Java内存模型与线程

第12章 Java内存模型与线程 Java内存模型  主内存与工作内存: java内存模型规定了所有的变量都在主内存中,每条线程还有自己的工作内存. 工作内存中保存了该线程使用的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行. 内存间交互操作: 1 lock 作用于主内存的变量,它把一个变量标识为一个线程独占的状态. 2 unlock 作用于主内存的变量,把锁定的变量释放出来 3 read 作用于工作内存的变量,把一个变量的值从主内存传输到线程的工作内存中. 4 load 作用于工作

深入理解Java内存模型(三)——顺序一致性

本文属于作者原创,原文发表于InfoQ:http://www.infoq.com/cn/articles/java-memory-model-3 数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java内存模型规范对数据竞争的定义如下: 在一个线程中写一个变量, 在另一个线程读同一个变量, 而且写和读没有通过同步来排序. 当代码中包含数据竞争时,程序的执行往往产生违反直觉的结果(前一章的示例正是如此).如果一个多线程程序能正确同步,这个程序将是一个没有数据竞争的程序. JMM对正

深入理解java内存模型

深入理解Java内存模型(一)——基础 并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递. 在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信.在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过明确的发送消息来显式进行通信. 同步是指程序用于控制不同线程之