zoukankan      html  css  js  c++  java
  • java多线程系列5 atomic简介

    先看一个例子,AtomicInteger 实现的线程安全的累加器

    public class AtomicIntTest {
    	public static void main(String[] args) {
    		AddRunnable addRunnable = new AddRunnable();
    		Thread myThread1 = new Thread(addRunnable);
    		Thread myThread2 = new Thread(addRunnable);
    		myThread1.start();
    		myThread2.start();
    		try {
    			myThread1.join();
    			myThread2.join();
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    
    		System.out.println(addRunnable.count);
    	}
    
    }
    
    class AddRunnable implements Runnable {
    	AtomicInteger count = new AtomicInteger();
    
    	@Override
    	public void run() {
    		for (int i = 0; i < 100000; i++) {
    			count.incrementAndGet();
    		}
    	}
    
    }
    

    AtomicInteger源码分析

           下面通过AtomicInteger的源码来看一下是怎么在没有锁的情况下保证数据正确性。首先看一下incrementAndGet方法的实现

          

    public final int incrementAndGet() {  
        for (;;) {  
            int current = get();  
            int next = current + 1;  
            if (compareAndSet(current, next))  
                return next;  
        }  
    }  
    
    
    public final boolean compareAndSet(int expect, int update) {     
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);  
    }  
    

      注意::valueOffset叫做 偏移量 我们知道valueOffset指向的地址对应的值就是原始变量的值 执行逻辑就是 expect 和valueOffset 比较 相同 就替换成 update 不同继续循环

     

     总结:

         

    虽然基于CAS的线程安全机制很好很高效,但要说的是,并非所有线程安全都可以用这样的方法来实现,这只适合一些粒度比较小,型如计数器这样的需求用起来才有效,否则也不会有锁的存在了。实际来发中,用锁的情况还是较多。

    并发越高,失败的次数会越多,CAS如果长时间不成功,会极大的增加CPU的开销。(毕竟死循环嘛) 因此CAS不适合竞争十分频繁的场景。

    3 CAS只能保证一个共享变量的原子操作。当对多个共享变量操作时,CAS就无法保证操作的原子性,这时就可以用锁,或者把多个共享变量合并成一个共享变量来操作。使用AtomicReference。

  • 相关阅读:
    hdu 1016 Prime Ring Problem (dfs)
    微信小程序尝鲜一个月现状分析
    创新大师Steve Blank: 你真的知道什么是真正的精益创业吗?
    android studio 开发经常使用快捷键使用分享
    LeetCode:Partition List
    2016 博客导读总结 &amp; 个人感悟
    poj
    Android开之在非UI线程中更新UI
    浅谈数据库生命周期
    从AdventureWorks学习数据库建模——保留历史数据
  • 原文地址:https://www.cnblogs.com/javabigdata/p/6842292.html
Copyright © 2011-2022 走看看