众所周知,AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。
要使用多处理器系统的功能,通常需要使用多线程构造应用程序。但是正如任何编写并发应用程序的人可以告诉你的那样,要获得好的硬件利用率,只是简单地在多个线程中分割工作是不够的,还必须确保线程确实大部分时间都在工作,而不是在等待更多的工作,或等待锁定共享数据结构。而synchronized来控制并发就需要去等待这个锁资源,这步是非常消耗资源的,处理的吞吐量也就下去了。而java的concurrent 并发包提供的AtomicInteger就提供CAS原理避免了锁等待,具体的实现是通过UnSafe类来直接操作底层的硬件资源。
CAS是Compare And Swap的简写。意思就是比较并交换。CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。对应到AtomicInteger的源码就是
/**
* Atomically increments by one the current value.
*
* @return the previous value
*/
public final int getAndIncrement() {
for (;;) {
int current = get();//使用volatile关键字修饰AtomicInteger 的value,在每次加1前都从主存中获取最新的value值。
int next = current + 1;
if (compareAndSet(current, next))//CAS比较并交换,如果这个current 还是原来那个,即没有其他线程修改到,那么就把加1后的新值替换以前的值。
return current;
}
用个for循环,就是在有其他线程改变了这个current值后不断的重试,去拿到最新的值去加1.通过这样的方式来保证线程的安全,和使用synchronized达到一样的效果。
}
下面是对加synchronized和 AtomicInteger的简单性能比较:
开3个线程,对自增操作性1000000 * 1000次。处理时间如下:
synchronized time elapse:461198
AtomicInteger time elapse:88507。
附件中有测试的代码
要使用多处理器系统的功能,通常需要使用多线程构造应用程序。但是正如任何编写并发应用程序的人可以告诉你的那样,要获得好的硬件利用率,只是简单地在多个线程中分割工作是不够的,还必须确保线程确实大部分时间都在工作,而不是在等待更多的工作,或等待锁定共享数据结构。而synchronized来控制并发就需要去等待这个锁资源,这步是非常消耗资源的,处理的吞吐量也就下去了。而java的concurrent 并发包提供的AtomicInteger就提供CAS原理避免了锁等待,具体的实现是通过UnSafe类来直接操作底层的硬件资源。
CAS是Compare And Swap的简写。意思就是比较并交换。CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。对应到AtomicInteger的源码就是
/**
* Atomically increments by one the current value.
*
* @return the previous value
*/
public final int getAndIncrement() {
for (;;) {
int current = get();//使用volatile关键字修饰AtomicInteger 的value,在每次加1前都从主存中获取最新的value值。
int next = current + 1;
if (compareAndSet(current, next))//CAS比较并交换,如果这个current 还是原来那个,即没有其他线程修改到,那么就把加1后的新值替换以前的值。
return current;
}
用个for循环,就是在有其他线程改变了这个current值后不断的重试,去拿到最新的值去加1.通过这样的方式来保证线程的安全,和使用synchronized达到一样的效果。
}
下面是对加synchronized和 AtomicInteger的简单性能比较:
开3个线程,对自增操作性1000000 * 1000次。处理时间如下:
synchronized time elapse:461198
AtomicInteger time elapse:88507。
附件中有测试的代码