zoukankan      html  css  js  c++  java
  • java多线程详解(8)-volatile,Atomic比较

    在变成过程中我们需要保证变量的线程安全,在java中除了使用锁机制或者Threadlocal等保证线程安全,还提供了

    java.util.concurrent.atomic.Atomic*(如AtomicInteger,AtomicLong等)原子类和volatile关键字是java中

    两种常见的处理多线程下数据共享读写的机制。

    二者看似相同,但是在实际应用中有着不小的差别。

    1.volatile关键字

    volatile关键字是通过本地代码实现的写锁,只保证知有一个线程在写某个数据。JVM为了提高数据存取的速度,

    允许每个线程在自己独立的数据块,对进程中共享的数据进行私有拷贝。volatile就是保证每次读数据时,

    读的都是存在共享数据块里的数据,而不是私有拷贝。然而,这种机制在有些情况下并不安全。

    当两个线程T1,T2同时对volatitle int i;作i++;时,可能出现问题。i++相当于为i=i+1。

    T1 load i
    
    T2 load i
    
    T1 store i+1
    
    T2 store i+1

    这里应该执行两次i=i+1,得到i=i+2的,但是结果确实i=i+1。

    因此,这边就有了Atomic原子类存在的价值了。Atomic类被设计来解决这个问题。

    2.Atomic* 原子操作

    关于atomic*原子操作,这里以AtomicInteger类为例

    使用场景:

    AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,

    不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。

    /**
     * Atomic原子性测试。
     * 
     * @author cary
     * @version 1.0.0
     */
    public class AtomicTest {
        public static void main(String[] args) {
            AtomicInteger ai = new AtomicInteger(0);
            int i1 = ai.get();
            print(i1);
            int i2 = ai.getAndSet(5);
            print(i2);
            int i3 = ai.get();
            print(i3);
            int i4 = ai.getAndIncrement();
            print(i4);
            print(ai.get());
        }
    
        static void print(int i) {
            System.out.println("i : " + i);
        }
    }

    结论: atomic比volatile靠谱

  • 相关阅读:
    XHTML基础问答-给初学者
    动态改变表格的行数列数(添加表格)
    记录的添加,修改,删除等操作,??
    数据绑定
    优秀ASP.NET程序员修炼之路
    关于Command的ExecuteNonQuery(),ExecuteScalar(),ExecuteReader方法的区别
    MyEclipse7.5注册
    实用JavaScript代码库
    解决数据库录入中文数据乱码问题
    Oracle占用8080端口问题的解决
  • 原文地址:https://www.cnblogs.com/weiguo21/p/4815962.html
Copyright © 2011-2022 走看看