首页 > 其他 > 详细

Java 7源码分析第23篇 - 多线程之原子类

时间:2014-02-03 13:45:29      阅读:423      评论:0      收藏:0      [点我收藏+]

在java.util.concurrent包里包含的主要就是一些与并发实现相关的类,首先来看一下最为基础的原子类(java.util.concurrent.atomic)和和线程锁(java.utl.concurrent.locks)。这一篇将着重讲解一下原子类。


在java.util.concurrent.atomic中都是一些命名形式为Atomic*的类,如AtomicInteger、AtomicLong等,拿Atomic举例来说,调用类中相关的方法可以肯定,能够返回一个唯一的数值。在这个类中有一个关键的变量定义如下:

private volatile int value;
这个私有的变量被volatile修饰,那么volatile关键字的作用是什么呢?
(1)可以使value在被某个线程修改后及时刷回到主内存中

(2)线程在获取value值时,这个值必须要从主内存中取出

可以看到,其实被volatile修饰的原始类型类似于一个小小的同步块,但是与同步块比起来,由于没有线程锁这样一个概念,所以在某些情况下还是得不到保证。例如要获取一个唯一增长的序列时,还是会产生问题。

举个例子:

public class UnsafeSequence {
    private volatile int value;
	public  int get() {
         return value++;
	}
}
在执行的时候,两个线程在调用get()方法时很可能会得到相同的值。如何能保证一个唯一且增长的序列时,可能会给get()方法上锁(加synchronized关键字或同步块),这时候就不需要volatile关键字了,因为如果给get()方法上锁,那么同步块本身会刷内存的。怎么利用volatile来实现呢?

下面继续来分析源码,发现这个类中提供了一些设置value值的方法,其中就包括对value值进行加1的操作,如下:

public final int getAndIncrement() {
        for (;;) {
            int current = get(); // 获取value当前值
            int next = current + 1;
            if (compareAndSet(current, next))
                return current;
        }
    }
还有comareAndSet()方法的源代码如下:

/**
     * Atomically sets the value to the given updated value
     * if the current value  == the expected value.
     */
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

当value值等于expect的时候,修改value的值为update,也就是给value值加1。可能有些人会问,为什么要比较value和expect的值呢?这就是设计的巧妙之处。

试想一下,如果value值为2的时候,被两个线程调用get()方法得到值后,其中线程1为value值加1后,调用compareAndSet()方法将value值修改为3并被刷回到内存中。线程2也要调用compareAndSet()方法时,这时的expect=2就和value=3的值不符合了,所以不会返回3,避免错误。

此时如何处理呢?在for(;;)死循环中重新作处理后,就可以得到正确的值4并且返回了。

下面我们来利用这个类得到 一个唯一且完全增长的序列,如下:

public class SafeSequence {
    private final AtomicInteger value=new AtomicInteger(0);
	public  int getSequence() {
         return value.getAndIncrement();
	}
}

















































Java 7源码分析第23篇 - 多线程之原子类

原文:http://blog.csdn.net/mazhimazh/article/details/18908493

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!