我是靠谱客的博主 坚强蚂蚁,最近开发中收集的这篇文章主要介绍JAVA高性能编程之线程安全原子性浅析线程安全原子性问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

线程安全原子性问题

什么是线程安全

当多个线程访问某一个类时,
不管运行时环境采用何种调度方式或者这些进程将如何交替执行,
并且在主调代码中不需要任何额外的同步或协同,
这个类都能表现出正确的行为,那么就称为是线程安全的。
线程安全的操作其中一个特性就是原子性。

怎样的操作会产生原子性问题

可看如下代码
在这里插入图片描述
多次执行这段代码可以发现,执行结果会产生小于60000的情况,结果表明i++这个操作并不是个原子性的操作,
那么原因在哪呢?
用javap命令编译Counter可得到字节码命令
在这里插入图片描述
由代码可以看到。i++操作分为4个步骤 首先当有线程执行时
1 线程会开辟独有的工作空间,并执行getfield,从堆内存中取出i的值。
2 执行iconst-1 将i的值写入操作数栈。
3执行iadd,进行累加操作。
4putfield,将操作数栈中的值写回堆内存中。
当只有一个线程执行时,操作没有问题,但同时有多个线程请求堆内存中i的值的时候,会导致请求到相同的i值,
导致该次执行失效。所以执行上面代码时会产生小于60000的情况

什么样的操作是原子操作

原子操作可以是一个步骤,也可以是多个步骤,但顺序不可以被打乱,也不可以被切割而只执行其中一部分
将整个操作视为一个整体。资源在该次操作中保持一致。这是原子性的核心特征

怎么实现原子操作

1 可以通过加锁的方式,即通过synchronized加锁,也可以是ReentrantLock加锁.
这种方式的原子操作,锁定了资源,使得整个操作变为单线程的串行操作,效率不高
synchronized 加锁
public class Counter {

volatile int i = 0;

public synchronized void increament() {
i++;
}
}
ReentrantLock 加锁
public class Counter {

volatile int i = 0;

Lock lock = new ReentrantLock();

public void increament() {
lock.lock();
i++;
lock.unlock();
}
}

2 通过JDK自带的AtomicInteger 实现原子操作,底层是由CAS实现,仍然使用多线程进行,效率会提高很多
AtomicInteger 实例
public class Counter {

AtomicInteger i= new AtomicInteger();

public void increament() {
i.incrementAndGet();
}
}

最后

以上就是坚强蚂蚁为你收集整理的JAVA高性能编程之线程安全原子性浅析线程安全原子性问题的全部内容,希望文章能够帮你解决JAVA高性能编程之线程安全原子性浅析线程安全原子性问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部