Java内存模型以及线程安全

更多请查看本人博客

1、Java内存模型

如下图所示,Java主要有5个存储区域,分别是方法区、堆区、Java栈、本地方法区、程序计数器。其中方法区和堆区是各个线程共有的。

1.1方法区

方法区存储了类型的各种有用信息,包括常量池、修饰符、类变量、类方法、类加载器等信息;程序在运行过程中要不断地访问方法区来获取类型信息。

1.2Java栈

程序代码、临时变量的引用都保存在Java栈中

1.3本地方法栈

本地方法栈用于线程中本地方法的调用,Java调用本地方法是非常常见的,例如Object的hashcode方法就是调用的本地方法。

1.4程序计数器

程序计数器是唯一一个不会被Java垃圾回收的地方。

1.5堆区

堆区存放了各种对象。

2、内存模型与线程安全

2.1来由

假设有一个对象x存放在堆中,线程A和线程B都会对对象x进行更改,而通常线程A和线程B都会维护一个对象x的拷贝,所有对对象x的操作都是在拷贝中进行的,那么就产生了下面两个问题:

1、不可见性

2、不一致性

不可见性的原因是当某个线程对对象x进行更改之后,其更改不会立即反馈给堆中的对象。导致这个操作对其他线程不可见。不一致性是由于多个线程对对象x同时进行了更改,这种更改先后不能够保证,导致同样的程序得到不一致的结果。解决这两个问题分别有如下的方法:

2.1、可见性

java中很多关键字都提供了可见性的支持,例如volatile,该关键字修饰的对象的更改会立即被其他线程看见。但是volatile的缺点是不具有原子性,因此使用volatile的地方要确保不会有多个线程同时对变量进行更改。

另外synchronized锁是具有可见性的,在进入synchronized代码块之前以及之后都会进行同步操作,将线程中的改动同步到堆中,使得其他的线程都能够看见。除此之外还有java.util.concurrent.lock包中的各种锁也具有同步功能。

2.2、一致性

一致性换个说法也就是原子性,也就是操作不可分割的意思。synchronized代码块以及lock,还有CAS操作都具有原子性。

2.3、不变性

最安全的线程安全方式就是不变性,不会变化的数据是不具有线程安全问题的,例如用final修饰的变量。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值