java多线程基础(四)–回顾学习历程,由浅及深,作为个人笔记,也希望帮到需要的人 (2)原子类 java中用于保证一组操作的原子性,除了使用synchronized添加同步锁以外,还可以使用原子类。 包含AtomicBoolean,AtomicInteger,AtomicIntegerArray等。 java原子类的实现原理基于CAS算法,是一种无锁的非阻塞算法,需要硬件的支持,采用“乐观锁”技术,更新前判断原值是否被其他线程改变,如果没有改变才执行set操作,否则回滚之前的修改,重新尝试。JVM在底层为原子类提供了CAS支持,java.util.concurrent包中的多数类实现时直接后间接使用了这些原子变量类。这是因为基于加锁的synchronized比无锁的CAS效率低很多,大多数情况下CAS都是一次成功,也就是不涉及争用,此时锁机制涉及CAS和一些额外的操作,自然比无锁的CAS慢一些;而有争用的情况下,CAS只是增加几个循环迭代,比锁机制的线程挂起和上下文切换开销还是小很多;不过如果频繁争用,CAS始终不能成功,可能出现锁机制效率更高的情况。原子类的使用如下:
//使用原子类过程为2步: //1.使用原子类定义新值,旧值 //2.do-while循环中使用原子类的CAS算法设值 //注:其他的用法包括自增 public class ConcurrentStack<E> { AtomicReference<Node<E>> head = new AtomicReference<Node<E>>(); public void push(E item) { Node<E> newHead = new Node<E>(item); Node<E> oldHead; do { oldHead = head.get(); newHead.next = oldHead; } while (!head.compareAndSet(oldHead, newHead)); } public E pop() { Node<E> oldHead = head.get(); Node<E> newHead; do { if (null == oldHead) { return null; } newHead = oldHead.next; } while (!head.compareAndSet(oldHead, newHead)); return oldHead.item; } } class Node<E> { final E item; Node<E> next; Node(E item) { this.item = item; } }参考:http://www.tuicool.com/articles/zuui6z
附:乐观锁,悲观锁 悲观锁:每次取数据都默认为别人会修改数据,所以每次操作之前都上锁。上锁之后别人就无法使用直到别人拿到锁。传统关系数据库使用的就是悲观锁 乐观锁:与悲观锁相反,认为别人不会改动,只会在更新数据的时候比较数据是否被修改(比如比较版本号等)。 乐观锁用于读操作比较多的时候,悲观锁用于写操作比较多的时候