integer java关键字_AtomicInteger关键字

validate 关键字可以保证多线程之间的可见性,但是不能保证原子操作。(需要了解java内存模型jmm)

packagecom.cn.test.thread;public class VolatileAutomic extendsThread{private volatile static int count = 0; public static voidadd() {for (int i = 0; i < 10000; i++) {

count ++;

}

}

@Overridepublic voidrun() {

add();

}public static voidmain(String[] args) {for (int i = 0; i < 10; i++) {newVolatileAutomic().start();

}while (Thread.activeCount() > 1) {

Thread.yield();

}//System.out.println(atomicCount.get());

System.out.println("count=" +count);

}

}

运行结果:

count=61618

上面例子中volatile关键字能保证可见性没有错,但是上面的程序错在没能保证原子性。可见性只能保证每次读取的是最新的值,但是volatile没办法保证对变量的操作的原子性。

count++是一个非原子性的操作,它包括读取变量的原始值、进行加1操作、写入工作内存。那么就是说自增操作的三个子操作可能会分割开执行,就有可能导致的情况:

假如某个时刻变量count的值为10,线程1对变量进行自增操作,线程1先读取了变量count的原始值,然后线程1被阻塞了;线程2也对变量进行自增操作,线程2先读取了count的原始值,线程1只是进行了读取操作,没有进行写的操作,所以不会导致线程2中的本地缓存无效,因此线程2进行++操作,在把结果刷新到主存中去,此时线程1在还是读取原来的10 的值在进行++操作,所以线程1和线程2对于count=10进行两次++操作,结果都为11.。

上述问题解决方法:

1.采用add方法中加入sychnorized.,或者同步代码块

2.采用AtomicInteger

packagecom.cn.test.thread;importjava.util.concurrent.atomic.AtomicInteger;public class VolatileAutomic extendsThread{static AtomicInteger atomicCount = new AtomicInteger(0);public static voidadd() {for (int i = 0; i < 10000; i++) {

atomicCount.incrementAndGet();

}

}

@Overridepublic voidrun() {

add();

}public static voidmain(String[] args) {for (int i = 0; i < 10; i++) {newVolatileAutomic().start();

}while (Thread.activeCount() > 1) {

Thread.yield();

}

System.out.println(atomicCount.get());

}

}

运行结果:

100000

AtomicInteger是java.util.concurrent.atomic并发包下面一个类。

AtomicInteger源码理解:

static{try{

valueOffset=unsafe.objectFieldOffset

(AtomicInteger.class.getDeclaredField("value"));

}catch (Exception ex) { throw newError(ex); }

}

/*** Creates a new AtomicInteger with the given initial value.

*

*@paraminitialValue the initial value*/

public AtomicInteger(intinitialValue) {

value=initialValue;

}

调用AtomicInteger的构造方法传入一个initialValue值,将initialValue复制给一个volatile 的value,

/**

* Atomically increments by one the current value.

*

* @return the updated value

*/

public final int incrementAndGet() {

return unsafe.getAndAddInt(this, valueOffset, 1) + 1;

}

public final int getAndAddInt(Object var1, long var2, int var4) {

int var5;

do {

var5 = this.getIntVolatile(var1, var2);

} while (!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

return var5;

}

底层源码实现主要采用cas算法的思想,通过操作底层硬件的指令。cas锁是一种无锁的机制。cas的机制:v的值应该是A,如果是A则将值更新为B。当多个线程同时要更新V的值,

只有其中一个线程更新成功,其他线程更新失败,更新失败的线程并不会挂起,而是在继续进行竞争资源,对V的值进行操作。

cas锁的机制采用的是事物提交-- 失败--重试来保证原子性。

cas锁的缺点:当并发量大的时候,多线程一直进行重试,这样会导致CPU的开销很大。

packagecom.cn.test.thread;importjava.util.concurrent.atomic.AtomicInteger;/*** 设计4个线程,其中两个线程 每次对j增加1,另外两个线程对j每次减少1。写出程序。

**/

public class TestAtomicThread extendsThread {private static int j = 10;static AtomicInteger atomicInteger = newAtomicInteger(j);publicTestAtomicThread(String string) {super(string);

}

@Overridepublic voidrun() {

System.out.println(Thread.currentThread().getName());switch(Thread.currentThread().getName()) {case "thread-1":case "threa-2":

atomicInteger.incrementAndGet();//System.out.println("当前线程名称:" + Thread.currentThread().getName() + ":" + atomicInteger.get());

break;case "thread-3":case "thread-4": atomicInteger.decrementAndGet();//System.out.println("当前线程名称:" + Thread.currentThread().getName() + ":" + atomicInteger.get());

break;default : break;

}

}public static voidmain(String[] args) {

TestAtomicThread t1= new TestAtomicThread("thread-1");

TestAtomicThread t2= new TestAtomicThread("thread-2");

TestAtomicThread t3= new TestAtomicThread("thread-3");

TestAtomicThread t4= new TestAtomicThread("thread-4");

t1.start();

t2.start();

t3.start();

t4.start();if (Thread.activeCount() > 1) {

Thread.yield();

}

System.out.println("j====" +atomicInteger.get());

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值