Java中unsafe操作執行個體總結,javaunsafe

來源:互聯網
上載者:User

Java中unsafe操作執行個體總結,javaunsafe

Unsafe是Java無鎖操作的基石,在無鎖並發類中都少不了它們的身影,比如ConcurrentHashMap, ConcurrentLinkedQueue, 都是由Unsafe類來實現的。相對於與Java中的鎖,它基本無開銷,會原地等待。本文主要介紹下Unsafe中的主要操作。

1 compareAndSwap

/*** 比較obj的offset處記憶體位置中的值和期望的值,如果相同則更新。此更新是不可中斷的。* * @param obj 需要更新的對象* @param offset obj中整型field的位移量* @param expect 希望field中存在的值* @param update 如果期望值expect與field的當前值相同,設定filed的值為這個新值* @return 如果field的值被更改返回true*/public native boolean compareAndSwapInt(Object obj, long offset, int expect, int update);

這個就是著名的CAS操作了,分為三步來做

  1. 擷取obj對象中為offset的位移值,這裡假設為realVal
  2. 比較realVal和expect
  3. 如果相同,將該值更新為update,否則不更新

CAS家族還包括有,compareAndSwapObject(), compareAndSwapLong(), compareAndSwapInt()等等

用AtomicInteger中一個經典的例子來說明:

public final int getAndAdd(int delta) {    return unsafe.getAndAddInt(this, valueOffset, delta);}//unsafe.getAndAddIntpublic final int getAndAddInt(Object var1, long var2, int var4) {  int var5;  do {  /**擷取原始值*/    var5 = this.getIntVolatile(var1, var2);  /**確認原始值沒有被其它線程修改時,再執行更新var5+var4操作*/  } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));  return var5;}

2 putOrder

/***  * Sets the value of the integer field at the specified offset in the  * supplied object to the given value. This is an ordered or lazy  * version of <code>putIntVolatile(Object,long,int)</code>, which  * doesn't guarantee the immediate visibility of the change to other  * threads. It is only really useful where the integer field is  * <code>volatile</code>, and is thus expected to change unexpectedly.  *  * @param obj the object containing the field to modify.  * @param offset the offset of the integer field within <code>obj</code>.  * @param value the new value of the field.  * @see #putIntVolatile(Object,long,int)  */ public native void putOrderedInt(Object obj, long offset, int value);

將obj對象的位移量為offset的位置修改為value,因為Java中沒有記憶體操作,而Unsafe的這個操作正好補充了記憶體操作的不足。也可以用於數組操作,比如ConcurrentHashMap中就大量用到了該操作

 Segment<K,V> s0 =    new Segment<K,V>(loadFactor, (int)(cap * loadFactor),             (HashEntry<K,V>[])new HashEntry[cap]);  Segment<K,V>[] ss = (Segment<K,V>[])new Segment[ssize];  // 往數組下標為0的位置,寫入s0: ss[0]=s0  UNSAFE.putOrderedObject(ss, SBASE, s0); // ordered write of segments[0]

需要注意的是obj需要設定為Volatile,否則對於其它線程會不可見

3 putXxxVolatile

/***  * Sets the value of the integer field at the specified offset in the  * supplied object to the given value, with volatile store semantics.  *  * @param obj the object containing the field to modify.  * @param offset the offset of the integer field within <code>obj</code>.  * @param value the new value of the field.  */ public native void putIntVolatile(Object obj, long offset, int value);

感覺和putOrderInt一樣,因為必須設定為Volatile,否則有什麼用呢?

以上就是本次給大家分享的知識點的全部內容,感謝大家對幫客之家的支援。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.