并发库应用之二 & Java原子性操作类应用

时间:2022-03-04 07:21:11

  Java5的线程并发库中,提供了一组atomic class来帮助我们简化同步处理。基本工作原理是使用了同步synchronized的方法实现了对一个long, integer, 对象的增、减、赋值(更新)操作

java.util.concurrent在并发编程中很常用的实用工具类。

|----locks为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器

|----atomic类的小工具包,支持在单个变量上解除锁的线程安全编程。可以对基本类型、数组中的基本类型、类中的基本类型等进行操作

|----AtomicInteger  用于提供整型数字原子性操作

           |----AtomicIntegerArray  用于提供整型数组原子性操作

           |----AtomicIntegerFieldUpdater  用于提供类对象中的整型数据原子性操作

           ......  对应有Double...相类似的原子性操作类

  以上原子性操作类具体如何使用详情可以查看相应的官方jdk文档,下面通过简单的两个例子的对比来看一下 AtomicInteger 的强大的功能,分别是普通的方法与使用AtomicInteger类的方法:

普通方法实现方案:

 public class CommonTest {
private volatile int count = 0; //volatile关键字实现线程间数据共享 public synchronized void increment() {
count++; //若要线程安全执行,需要加锁
} public int getCount() {
return count;
}
}

使用AtomicInteger类的方法实现

 public class AtomicIntegerTest {
private AtomicInteger count = new AtomicInteger(); public synchronized void increment() {
count.incrementAndGet();
} public int getCount() {
return count.get();
}
}

调用两个类的主方法实现

 public class MainClass {
public static void main(String[] args) {
//final CommonTest atomicIntegerTest = new CommonTest();
final AtomicIntegerTest atomicIntegerTest = new AtomicIntegerTestTrue();
for (int j = 0; j < 3; j++) { //各自同时开启3个线程
//增加线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
atomicIntegerTest.increment();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
//读取线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "-->" + atomicIntegerTest.getCount());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
}

运行结果如下所示:

Thread-1-->1
Thread-3-->2
Thread-5-->3
Thread-3-->4
Thread-1-->5
Thread-5-->5
Thread-1-->9
Thread-5-->9
Thread-3-->9
Thread-5-->12
Thread-3-->12
Thread-1-->12
Thread-3-->13
Thread-1-->13
Thread-5-->14
Thread-5-->16
Thread-1-->16
Thread-3-->16
Thread-1-->21
Thread-3-->21
Thread-5-->21
Thread-5-->22
Thread-1-->22
Thread-3-->22
Thread-1-->25
Thread-5-->25
Thread-3-->25
Thread-3-->29
Thread-1-->30
Thread-5-->29

  从上面的例子中我们可以看出:使用AtomicInteger是非常的安全的

  那么为什么不使用记数器自加呢,例如count++这样的,因为这种计数是线程不安全的,高并发访问时统计会有误,而AtomicInteger为什么能够达到多而不乱,处理高并发应付自如呢?

  这是由硬件提供原子操作指令实现的。在非激烈竞争的情况下,开销更小,速度更快。

提示:常用基本类的原子操作讲解完毕,接下来我们就开始进入有关多线程线程池相关概念讲解,具体详情请查看我的下一篇博客:并发库应用之三 & 线程池与定时器应用