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 AtomicIntegerFieldUpdaternewUpdater(Class tclass,
String fieldName)
使用方法:
private AtomicIntegerFieldUpdater
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.
*
* 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.
*
* 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.
*
* 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
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); 构造后成了一个线程安全的变量。