看一个计数的类:
- public class Counter {
- private static long counter = 0;
- public static long addOne(){
- return ++counter;
- }
- }
初看感觉没啥问题,但这个类在多线程的环境下就会有问题了。
假如开多个线程都来使用这个计数类,它会表现的“不稳定”
- public static void main(String[] args) {
- for(int i=0;i<100;i++){
- Thread thread = new Thread(){
- @Override
- public void run() {
- try {
- Thread.sleep(100);
- if(Counter.addOne() == 100){
- System.out.println("counter = 100");
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- };
- thread.start();
- }
- }
程序会开100个线程,每个线程都会把counter 加一。那么应该有一个线程拿到counter =100的值,但实际运行情况是大多数据情况下拿不到100,在少数情况能拿到100.
因为 Counter 类在 addOne()方法被调用时,并不能保证线程的安全,即它不是原子级别的运行性,而是分多个步骤的,打个比方:
线程1首先取到counter 值,比如为10,然后它准备加1,这时候被线程2占用了cpu,它取到counter为10,然后加了1,得到了11。这时线程1 又拿到了CPU资源,继续它的步骤,加1为11,然后也得到了11。这就有问题了。
那么怎么解决它呢?JDK在concurrent包里提供了一些线程安全的基本数据类型的实现,比如 Long型对应的concurrent包的类是AtomicLong。
现在修改下代码:
- import java.util.concurrent.atomic.AtomicLong;
- public class Counter {
- private static AtomicLong counter = new AtomicLong(0);
- public static long addOne() {
- return counter.incrementAndGet();
- }
- }
运行了多次,结果都是能输出counter = 100。
所以在多线程环境下,可以简单使用AtomicXXX 使代码变得线程安全。
转载请注明出处:http://blog.csdn.net/yaqingwa/article/details/17737771
相关推荐
原子操作:JUC提供了一些原子操作类,如AtomicInteger、AtomicLong等,可以实现线程安全的原子操作,避免了使用synchronized关键字的性能损耗。 锁机制:JUC提供了Lock接口和Condition接口,可以实现更细粒度的锁...
2.2.2 原子类(AtomicInteger,AtomicLong,AtomicReference) 13 2.3 线程本地存储(Java.lang.ThreadLocal) 15 2.4 线程阻塞 17 2.4.1 调用sleep(millisecond)使任务进入休眠状态 17 2.4.2 等待输出与输入 17 2.4.3...
主要介绍了Java中对AtomicInteger和int值在多线程下递增操作的测试,本文得出AtomicInteger操作 与 int操作的效率大致相差在50-80倍上下的结论,需要的朋友可以参考下
多线程 第4章-多线程 Синхронные и асинхронные операции ...线程安全集合-并发集合 CopyOnWriteArrayList<E> CopyOnWriteArraySet<E> - аналог "Set" ConcurrentMap<K>
JUC 提供了线程安全的并发集合类,如 ConcurrentHashMap、ConcurrentLinkedQueue 等。 3. 原子操作(Atomic Operations): 原子操作是不可再分割的基本操作,JUC 提供了一系列原子操作类,如 AtomicInteger、...
迅雷笔试题java Java并发编程:03-多线程并发下载器, 支持断点下载(手写...守护线程的使用 06 原子增长类: AtomicLong 07 计时器的使用CountDownLatch 08 并发量的控制(信号量): Semaphore 09 阻塞队列的使用: Lin
java.util.concurrent.CountDownLatch通过org.redisson.core.RTopic 实现分布式订阅/发布通过 org.redisson.core.RHyperLogLog 实现分布式HyperLogLog 线程安全支持 OSGi超过110个单元测试 标签:Redisson...
它还使用AtomicLong 和AtomicDouble 来确保统计信息的生成也是线程安全的。POST : /transactions需要一个类型为application/json的JSON请求主体,格式为: {"amount":47,"timestamp":1525694370380}如果交易有效,...
│ 高并发编程第一阶段24讲、线程间通信快速入门,使用wait和notify进行线程间的数据通信.mp4 │ 高并发编程第一阶段25讲、多Produce多Consume之间的通讯导致出现程序假死的原因分析.mp4 │ 高并发编程第一阶段26...
│ 高并发编程第一阶段24讲、线程间通信快速入门,使用wait和notify进行线程间的数据通信.mp4 │ 高并发编程第一阶段25讲、多Produce多Consume之间的通讯导致出现程序假死的原因分析.mp4 │ 高并发编程第一阶段26...
Redisson-Redis Java客户端具有内存中... 线程安全的实现 API API API 异步连接池 Lua脚本 本地缓存支持,包括基于的实现 对象持有人,二进制流持有人,地理空间持有人,BitSet,AtomicLong,AtomicDouble,Publish
线程安全性 原子性-Atomic包 AtomicXXX:CAS、Unsafe.compareAndSwapInt AtomicLong、LongAdder AtomicReference、AtomicReferenceFieldUpdater AtomicStampReference:CAS的ABA问题 原子性-synchronized 修饰代码块...
字段必须是volatile类型的,在线程之间共享变量时保证立即可见 字段的描述类型( 修饰符public/protected/default/private )是与调用者与操作对象字段的关系一致。 也就是说调用者能够直接操作对象字段 ,...
AtomicLong在高并发下性能甚至还不如加锁,LongAdder比AtomicLong更适用于高并发下的累加TODO后续研究其原理 强引用,软引用,弱引用,幽灵引用,引用数量 强引用:StrongReference 例如Date date = new Date();...
阻塞队列 COEN 283 的阻塞队列项目 通过阻塞队列传递消息 ... 在自旋等待期间使用 LockSupport,并使用 AtomicLong 来读取和写入地址。 使用 ArrayBlockingQueue 的消息缓冲区 线程观察者监控线程生产者和消费者的效率
线程数## Programacion Java 2015-I ###并发变量Atomicas 锁辛克罗尼兹多斯(Sincronizados) 并发收集框架### Variables Atomicas ###### a)标量原子变量AtomicInteger / AtomicLong / AtomicBoolean ###### b)...