Java.util.concurrent两个子包locks&atomic,官网文档介绍为可以对基本数据、数组中的基本数据、对类中的基本数据进行操作。
一 atomic包
1. 原子性定义:原子性意味着个时刻,只有一个线程能够执行一段代码,这段代码通过一个monitor object保护,从而防止多个线程在更新共享状态时相互冲突。经过atomic类修饰的变量具备原子性,不必考虑在多线程并发条件下的线程安全问题。
(2)对类中的某个成员变量进行修改
使用方法:
//导入concurrent包下面的AtomicInteger内容 import java.util.concurrent.atomic.AtomicInteger; public class TestAtomic {// 测试concurrent包下的AtomicInteger public static AtomicInteger i = new AtomicInteger(0);// 所有的线程操作同一个对象 public static int A = 0; public static void main(String[] args) throws InterruptedException { System.out.println("i累计前"+TestAtomic.i+",A累计前:"+TestAtomic.A); Thread t0= new Thread( new Runnable(){ @Override public void run() { for(int j=0;j<100000;j++) { TestAtomic.A++; TestAtomic.i.getAndIncrement(); } } }); Thread t1= new Thread( new Runnable(){ @Override public void run() { for(int j=0;j<100000;j++) { TestAtomic.A--; TestAtomic.i.decrementAndGet(); } } }); t0.start(); t1.start(); t0.join(); t1.join(); System.out.print("i累计后"+TestAtomic.i+",A累计后:"+TestAtomic.A); } }
上述代码的运行结果为:
i累计前0,A累计前:0
i累计后0,A累计后:24531
从上述代码中我们可以看出,变量i保证了结果的正确性,原因在于i采用的是AtomicInteger 属性,变量具备原子性,从而保证了该变量是线程安全的。
(2)对已经new出来的某个变量进行修改,保证其原子性。
AtomicIntegerFieldUpdater使用最重要的在于其构造函数,我们可以在其api文件中查看
public static <U> AtomicIntegerFieldUpdater<U>newUpdater(Class<U> tclass,
String fieldName)
使用方法:
private AtomicIntegerFieldUpdater<Details>
atomicIntegerFieldUpdater = AtomicIntegerFieldUpdater.newUpdater(
Details.class, "numberTimesInvoked" );
详细使用代码:
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; /** * volatiles cannot be used directly in operations that do x = x + 1 for * numbers can be skipped or duplicated when there are multiple threads * involved. * <p> * Hardware supports Atomic Compare And Swap operations. CAS java classes * like AtomicInteger can use this feature of the hardware to ensure that * a "x = x + 1" like operation is atomic. * <p> * However AtomicInteger is significantly more resource intensive than a simple * volatile. If there are many instances of a class which has an AtomicInteger * this increase in resource over a volatile can be significant. * <p> * The AtomicIntegerFieldUpdater comes to the rescue - it can be registered * with a volatile variable of a class and can then be used on multiple * instances of the class. * * If there are 1000s of instances of a class which would ordinarily have * AtomicInteger this can be a big saving. * * AtomicIntegerFieldUpdater is able to update a volatile field of an object * atomically. * * @author John Dickerson */ public class AtomicIntegerFieldUpdaterCounter { // AtomicIntegerFieldUpdater is registered with Details.class so that it // knows it will later be updating the volatile field called // numberTimesInvoked //步骤1 构造方法 private AtomicIntegerFieldUpdater<Details> atomicIntegerFieldUpdater = AtomicIntegerFieldUpdater.newUpdater( Details.class, "numberTimesInvoked" ); /** * Diferent threads can call this method to update the volatile field of * an instance of Details * * @param details Details object which has the volatile field called * "numberTimesInvoked" in it. * * @return the value of the counter after it has been incremented by one */ //步骤2 对AtomicIntegerFieldUpdater修饰的变量进行操作 public int addOne( Details details ){ // performs a "x = x + 1" style atomic operation //return atomicIntegerFieldUpdater.addAndGet( details, 1 ); return this.atomicIntegerFieldUpdater.getAndIncrement(details); } public int subOne(Details details) { return atomicIntegerFieldUpdater.decrementAndGet(details); } /** * See test class for example of using this class with multiple threads, * some of which are writing to the volatile field and some which are * reading from the volatile field * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { final AtomicIntegerFieldUpdaterCounter atomicIntegerFieldUpdaterCounter = new AtomicIntegerFieldUpdaterCounter(); // This call would ordinarily be made by many other threads final Details d=new Details(); System.out.print("对象d的变量numberTimesInvoked累计前:"+d.getNumberTimesInvoked()); System.out.println(",A累计前:"+TestAtomic.A); Thread t0= new Thread( new Runnable(){ @Override public void run() { for(int j=0;j<100000;j++) { atomicIntegerFieldUpdaterCounter.addOne(d); TestAtomic.A++; } } }); Thread t1= new Thread( new Runnable(){ @Override public void run() { for(int j=0;j<100000;j++) { TestAtomic.A++; atomicIntegerFieldUpdaterCounter.subOne(d); } } }); t0.start(); t1.start(); t0.join(); t1.join(); System.out.print("对象d的变量numberTimesInvoked累计后:"+d.getNumberTimesInvoked()); System.out.println(",A累计后:"+TestAtomic.A); } }
/** * @author John Dickerson */ public class Details { volatile int numberTimesInvoked; public int getNumberTimesInvoked() { return numberTimesInvoked; } public void setNumberTimesInvoked(int numberTimesInvoked) { this.numberTimesInvoked = numberTimesInvoked; } }
运行结果如下:
对象d的变量numberTimesInvoked累计前:0,A累计前:0
对象d的变量numberTimesInvoked累计后:0,A累计后:199947
从上述代码中我们可以看出,新创建的:Details d=newDetails();对象d的变量numberTimesInvoked,经过this.atomicIntegerFieldUpdater.getAndIncrement(d); 构造后成了一个线程安全的变量。