并发主题

Java硬件事务内存

  硬件事务内存(Hardware Transaction Memory,简称HTM)能够允许多个线程同时投机地访问相同的数据结构,让高速缓存一致性协议(cache coherence protocol )确定是否发生了冲突,HTM旨在提供细粒度锁,简化锁以及在性能上接近无锁等其他可扩展性。JVM支持的HTM能让你的程序或库在很少修改情况下扩展到多核。换句话说,它允许多个线程并发执行synchronized 同步块,哪怕是并发写操作。

HTM是什么?

   硬件事务内存HTM已经存在了一段时间,以前一直不是主流。随着英特尔推出他们的第四代酷睿i3/i5/i7处理器(Haswell)和E3-1200 V3(最多4个核心)系列处理器,这才意味着HTM将真正发挥作用。 AFAIK,AMD公司计划尽快添加此功能。顺便说一句Azul的Vega的系统有这样的技术,你购买的硬件技术也许已经做到这一点。许多有Haswell处理器笔记本电脑已经有显著的功耗改善。

HTM如何工作?

  synchronized块是在Java中经常使用的,同步锁往往比优化的锁更粗粒度,如Hashtable在发生任何操作时锁定整个对象/Map,而ConcurrentHashMap有细粒锁定。编写一个细粒度锁是很难的。硬件事务内存的目标是支持粗粒度锁,但能得到细粒锁的优点。

1 private final Map map = new HashMap<>();
2  
3 public synchronized PooledObject acquireObject(String key) {
4     PooledObject object = map.get(key);
5     if (object == null)
6         map.put(key, object = new PooledObject());
7     return object;
8 }

这段代码使用synchronized,因为你不希望两个线程同时更新同一个Key。而你希望的是多线程如同无锁一样并发执行这段代码,或者CPU或JVM能够对这段代码进行自动优化。

如果没有HTM,这个同步块将会获得一个锁,使得这个方法访问变成顺序序列化访问,无论是读操作还是写操作。

使用HTM以后的字节码伪代码如下:


01 public PooledObject acquireObject(String key) {
02     int code;
03     do {
04         xbegin();
05         PooledObject object = map.get(key);
06         if (object == null)
07             map.put(key, object = new PooledObject());
08         return object;
09     } while((code = xend()) == RETRYABLE);
10     if (code != DONE) {
11         // take corrective action such as
12         // obtain a normal lock and repeat
13     }
14 }

该XEND指令对缓存进行检查是否存在可投机的读和写,看看是否有任何这些访问的任何高速缓存行被另一个CPU/线程修改。如果没有,所做的更改被提交。否则,任何更改都将被丢弃,不断重复循环。注意:回滚事务意味着撤销所作的更改。

更详尽的讨论:Gil Tene’s post on the mechanical sympathy


java多线程

Java同步或锁

Java性能调优