java.util.concurrent包分成了三个部分,分别是java.util.concurrent、java.util.concurrent.atomic和java.util.concurrent.locks。内容涵盖了并发集合类、线程池机制、同步互斥机制、线程安全的变量更新工具类、锁等等常用工具。
java.util.concurrent.locks:
多线程编程中常常要锁定某个对象,之前会用synchronized来实现,现在又多了另一种选择,那就是java.util.concurrent.locks。通过Lock能够实现更灵活的锁定机制,它还提供了很多synchronized所没有的功能,例如尝试获得锁(tryLock())。使用Lock时需要自己获得锁并在使用后手动释放,这一点与synchronized有所不同,在多线程并发性能上jdk1.5中lock性能较高,jdk1.6中synchronized有所改善,两者性能差不多。后续文章中我们会对synchronized和lock 做一个比较。
java.util.concurrent.atomic:
提供了原子操作。
多个线程执行一个操作时,其中任何一个线程要么完全执行完此操作,要么没有执行此操作的任何步骤,那么这个操作就是原子的。出现原因: synchronized的代价比较高。
对变量的读写操作都是原子操作(除了long或者double的变量),但像数值类型的++ --操作不是原子操作,像i++中包含了获得i的原始值、加1、写回i、返回原始值,在进行类似i++这样的操作时如果不进行同步问题就大了。好在java.util.concurrent.atomic为我们提供了很多工具类,可以以原子方式更新变量。
以下以AtomicInteger为例:
- int addAndGet(int delta):以原子方式将给定值与当前值相加。 实际上就是等于线程安全版本的i =i+delta操作。
- boolean compareAndSet(int expect, int update):如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。 如果成功就返回true,否则返回false,并且不修改原值。
- int decrementAndGet():以原子方式将当前值减 1。 相当于线程安全版本的–i操作。
- int getAndAdd(int delta):以原子方式将给定值与当前值相加。 相当于线程安全版本的t=i;i+=delta;return t;操作。
- int getAndDecrement():以原子方式将当前值减 1。 相当于线程安全版本的i–操作。
- int getAndIncrement():以原子方式将当前值加 1。 相当于线程安全版本的i++操作。
- int getAndSet(int newValue):以原子方式设置为给定值,并返回旧值。 相当于线程安全版本的t=i;i=newValue;return t;操作。
- int incrementAndGet():以原子方式将当前值加 1。 相当于线程安全版本的++i操作。
java.util.concurrent:
提供了很多并发的工具类,比如并发集合类ConcurrentHashMap、ConcurrentLinkedQueue和CopyOnWriteArrayList等等,根据不同的使用场景,我们可以替换以前常用的非线程安全的ArrayList、HashMap等集合类。