前言:
AtomicInteger在多线程程序中使用比较多,为什么要使用这个AtomicInteger呢,下面我们就来介绍一下。

AtomicInteger

AtomicInteger是一个提供原子操作的Integer类,通过线程安全的方式操作加减。
AtomicInteger提供原子操作来进行Integer的使用,因此十分适合高并发情况下的使用。

源码

public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;

// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;

static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
private volatile int value;
}

这只是其中部分源码,并没有放全,从这里我们可以看到value是使用volatile关键字修饰的,这样的作用是使得多个线程可以共享变量,但是问题在于使用volatile将使VM优化失去作用,导致效率降低。

AtomicInteger代码样例

写一个简单的应用:

package com.asong.cloud;

import java.util.concurrent.atomic.AtomicInteger;

public class TestAtomicInteger {
private static AtomicInteger atomicInteger = new AtomicInteger(0);
public static void testWithAtomic(){
for (int i = 0; i < 10; ++i) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
}catch (Exception e) {
e.printStackTrace();
}
System.out.println(atomicInteger.incrementAndGet());

}
}).start();
}
}

public static void main(String[] args) {
testWithAtomic();
}

}

总结

AtomicInteger是在使用非组赛算法实现并发控制,在一些高并发程序中很合适。
也在最后两个知识点,很重要。

非阻塞同步和阻塞同步

同步:多线程并发访问共享数据时,保证共享数据在同一时刻只被一个或一些线程使用。
阻塞同步和非阻塞同步都是实现线程安全的保障手段,非阻塞同步对于阻塞同步而言解决了阻塞同步中线程阻塞和唤醒带来的性能问题。在并发环境下,某个线程对共享变量先进行操作,如果没有其他线程争用共享数据那操作就成功。如果存在数据的冲突,那就采用补偿措施,不断地重试机制,直到成功为止,这种乐观的并发策略不需要把线程挂起,也就把这种同步操作称为非阻塞同步(操作和冲突检测具备原子性)。

synchroized

  1. 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
  2. 然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
  3. 尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
  4. 当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。