原子操作的实现原理

前言

要讲原子之前首先讲一下为什么要引入原子(个人理解)。很多情况下,我们的程序里面都会出现共享的数据,然后再多个线程里面对数据进行处理。例如自加或者自减,如果吗诶有进行额外的操作,单纯的自加自减在线程里面是不安全的。什么叫做不安全呢?简单来说就是得到的结果往往不是你所希望的。

什么是原子操作?

原子本意是“不能被分割的最小粒子”,所以原子操作就是“不可被中断的一个或者一系列操作”。如果多个处理器同时对共享变量进行读改写操作,这就不是原子操作。这样子的操作就是不安全的,也就是上面提到的无法得到预期的结果。下面进行代码测试

package programmingCAS;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class Counter {
private AtomicInteger atomicI=new AtomicInteger(0);
private int i=0;
public static void main(String[] args) {
	final Counter css=new Counter();
	List<Thread> ts=new ArrayList<Thread>(600);
	long start=System.currentTimeMillis();
	for(int j=0;j<100;j++) {
		Thread t=new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO 自动生成的方法存根
				for(int i=0;i<10000;i++)
					{
					css.count();
				     css.safeCount();
				     }
			}
			
		});
		ts.add(t);
	}
		for(Thread t:ts)
		{
			t.start();
		}
		for(Thread t:ts) {
			try {
				t.join();
			}
		catch(InterruptedException e)
		{
			e.printStackTrace();
		}}
		System.out.println(css.i);
		System.out.println(css.atomicI.get());
		System.out.println(System.currentTimeMillis()-start);
}
private void safeCount() {
	for(;;) {
		int i=atomicI.get();
		boolean suc=atomicI.compareAndSet(i, ++i);
		if(suc) {
			break;
		}
	}
}
private void count() {
	i++;
}
}

运行程序两次,得到的结果分别为:
在这里插入图片描述
在这里插入图片描述
其中,safeCount是原子操作,所以它得到的结果都是1000000.符合预期,而count方法是非原子操作,所以它几次运行的结果都是不一样的,也不是所预期的结果。
这是为什么呢?
查看代码,发现,safeCount方法调用了AtomicInteger类的compareAndSet方法,compareAndSet方法有两个参数,表示如果atomicI.get()得到的值的大小为i时,就自加1,变成第二个参数。
查看源代码
可以看到,compareAndSet()调用的就是Unsafe.compareAndSwapInt()方法,即Unsafe类的CAS操作。

什么是循环CAS?

CAS就是compare and swap,比较和交换,所以它需要提供三个值,一个是内存空间V,一个是旧值A,新值B,首先比较旧值是否为A,若是,则改为B。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值