J.U.C体系进阶(三)- juc-atomic 原子类框架

Java - J.U.C体系进阶

作者:Kerwin

邮箱:806857264@qq.com

说到做到,就是我的忍道!

juc-atomic 原子类框架

AtomicInteger

AtomicInteger即进行原子操作,CAS,有关CAS的可以详细再去查一查,涉及到C,汇编,硬件层面了,该类主要运用于多线程下的变量修改

主要涉及其自增,自加,set相关方法,适用场景:适合快速变量操作的场景,最简单的例子:比如统记网站访问人数,延申:自旋锁

public class AtomicIntegerTest {
	private static final ExecutorService pool = Executors.newFixedThreadPool(50);

	private static AtomicInteger surplusTickets = new AtomicInteger(100);// 余票量
	private static int surplusThread = 500;// 统计进程执行量,在进程都执行完毕后才关闭主线程
	
	private static AtomicInteger total = new AtomicInteger(0);
	
	public static void main(String[] args) throws InterruptedException {
		Date beginTime = new Date();  
		for (int i = 0; i < surplusThread; i++) {
			final int runNum = i;
			pool.execute(new Runnable() {
				public void run() {
					boolean getted = takeTicket();
					String gettedMsg = "";
					if (getted) {
						gettedMsg = "has getted";
						total.incrementAndGet();
					} else {
						gettedMsg = "not getted";
					}
					
					System.out.println("thread " + runNum + " " + gettedMsg + ", remain: " + surplusTickets
							+ ", line up:" + surplusThread + "..");
				}
			});
		}

		while (surplusThread >= 30) {
			sleep(100);
		}
		
		Date overTime = new Date();
		System.out.println("take times:" + (overTime.getTime() - beginTime.getTime()) + " millis.");
		System.out.println("total is: " + total);
	}


	/**
	 * 拿出一张票
	 */
	private static boolean takeTicket() {
		boolean result = false;
		sleep(30);
		if (surplusTickets.decrementAndGet() >= 0) {
			result = true;
		} else {
			surplusTickets.set(0);
		}
		surplusThread -= 1;
		return result;
	}

	/**
	 * 睡觉觉
	 */
	private static void sleep(int millis) {
		try {
			Thread.sleep(millis);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

CAS 是整个编程重要的思想之一。整个计算机的实现中都有CAS的身影。微观上看汇编的 CAS 是实现操作系统级别的原子操作的基石。从编程语言角度来看 CAS 是实现多线程非阻塞操作的基石。宏观上看,在分布式系统中,我们可以使用 CAS 的思想利用类似Redis的外部存储,也能实现一个分布式锁。
从某个角度来说架构就将微观的实现放大,或者底层思想就是将宏观的架构进行微缩。计算机的思想是想通的,所以说了解底层的实现可以提升架构能力,提升架构的能力同样可加深对底层实现的理解。计算机知识浩如烟海,但是套路有限。抓住基础的几个套路突破,从思想和思维的角度学习计算机知识。不要将自己的精力花费在不停的追求新技术的脚步上,跟随‘start guide line’只能写一个demo,所得也就是一个demo而已。
停下脚步,回顾基础和经典或许对于技术的提升更大一些

AtomicReference

针对普通对象级别的CAS操作,以无锁方式访问共享资源的能力 ,但是原子操作有一个ABA问题,所以一般情况下用的也不过,有兴趣的再自己搜一搜吧

AtomicXXXFieldUpdater

针对普通对象级别单一属性修改的CAS操作,以无锁方式访问共享资源的能力 ,但是原子操作有一个ABA问题,所以一般情况下用的也不过,有兴趣的再自己搜一搜吧

更强的原子类-LongAdder

LongAdder可以显著提升高并发环境下的性能

基础操作和AtomicInteger,AtomicLong相似

总之,低并发、一般的业务场景下AtomicLong是足够了。如果并发量很多,存在大量写多读少的情况,那LongAdder可能更合适

LongAdder的优化思路:

AtomicLong的实现方式是内部有个value 变量,当多线程并发自增,自减时,均通过cas 指令从机器指令级别操作保证并发的原子性

LongAdder则是采用了分段思想,将单一value的更新压力分担到多个value中去,降低单个value的 “热度”,分段更新

原文地址:https://www.cnblogs.com/kkzhilu/p/12859507.html