少年阿賓

          那些青春的歲月

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks
               在看 Java并發包(java.util.concurrent)中大量使用了CAS操作,CAS即 Compare And Swap(CAS),比較并交換,其中由sun.misc.Unsafe實現,Unsafe類提供了硬件級別的原子操作,Java無法直接訪問到操作系統底層(如系統硬件等),為此Java使用native方法來擴展Java程序的功能。具體實現使用c++。 牛B,**Unsafe類提供了硬件級別的原子操作**,但到底是什么意思呢?CAS從字面意思上就有兩部分:1、讀取并比較;2、判斷并決定是否交換。然后把這兩步驟作為原子操作,這樣就能保證線程安全
               幾句關于Unsafe的并發性。compareAndSwap方法是原子的,并且可用來實現高性能的、無鎖的數據結構。比如,考慮問題:在使用大量線程的共享對象上增長值。...
               Java是一門安全的編程語言,防止程序員犯很多愚蠢的錯誤,它們大部分是基于內存管理的。但是,有一種方式可以有意的執行一些不安全、容易犯錯的操作,那就是使用Unsafe類。
              CAS操作有3個操作數,內存值M,預期值E,新值U,如果M==E,則將內存值修改為B,否則啥都不做。
              sun.misc.Unsafe這個類是如此地不安全,以至于JDK開發者增加了很多特殊限制來訪問它。它的構造器是私有的,工廠方法getUnsafe()的調用器只能被Bootloader加載。如你在下面代碼片段的第8行所見,這個家伙甚至沒有被任何類加載器加載,所以它的類加載器是null。它會拋出SecurityException 異常來阻止侵入者。
              public final class Unsafe {
             ...
             private Unsafe() {}
             private static final Unsafe theUnsafe = new Unsafe();
             ...
             public static Unsafe getUnsafe() {
                Class cc = sun.reflect.Reflection.getCallerClass(2);
                if (cc.getClassLoader() != null)
                    throw new SecurityException("Unsafe");
                return theUnsafe;
             }
             ...
          }
          幸運的是這里有一個Unsafe的變量可以被用來取得Unsafe的實例。我們可以輕松地編寫一個復制方法通過反射來實現,如下所示:
          http://highlyscalable.wordpress.com/2012/02/02/direct-memory-access-in-java/
          public static Unsafe getUnsafe() {
             try {
                     Field f = Unsafe.class.getDeclaredField("theUnsafe");
                     f.setAccessible(true);
                     return (Unsafe)f.get(null);
             } catch (Exception e) {
                 /* ... */
             }
          }

          Unsafe一些有用的特性

          1. 虛擬機“集約化”(VM intrinsification):如用于無鎖Hash表中的CAS(比較和交換)。再比如compareAndSwapInt這個方法用JNI調用,包含了對CAS有特殊引導的本地代碼。在這里你能讀到更多關于CAS的信息:http://en.wikipedia.org/wiki/Compare-and-swap
          2. 主機虛擬機(譯注:主機虛擬機主要用來管理其他虛擬機。而虛擬平臺我們看到只有guest VM)的sun.misc.Unsafe功能能夠被用于未初始化的對象分配內存(用allocateInstance方法),然后將構造器調用解釋為其他方法的調用。
          3. 你可以從本地內存地址中追蹤到這些數據。使用java.lang.Unsafe類獲取內存地址是可能的。而且可以通過unsafe方法直接操作這些變量!
          4. 使用allocateMemory方法,內存可以被分配到堆外。例如當allocateDirect方法被調用時DirectByteBuffer構造器內部會使用allocateMemory
          5. arrayBaseOffsetarrayIndexScale方法可以被用于開發arraylets,一種用來將大數組分解為小對象、限制掃描的實時消耗或者在大對象上做更新和移動。

          Unsafe.java是jdk并發類庫java.util.concurrent包中使用的底層類,該類中的方法都是通過native方法調用操作系統命令。

              在多線程環境下,主要存在兩種特殊的場景:

              1;多個線程同時訪問某個對象的方法,由于操作系統對線程調度的不確定性,存在使該對象的狀態處于不一致的狀態,為了避免這種情況的發生,我們可以聲明該方法為同步方法(synchronized)。保證某一時刻只有一個線程調用該方法,其它調用線程則被阻塞。這種方法在并發性很高的情況下會產生大量的線程調度開銷。從而影響程序的并發性能。在java.util.concurrent包中通過使用非阻塞原子方法,減少操作系統的無用線程調度開銷,從而提高并發性能。

             2;多線程通過某個對象進行通信,即常見的生產者消費者模型。在以前的jdk版本中是通過wait,notify方法實現的。該方法也是通過底層在某個信號量上的阻塞隊列實現的。而Unsafe類中直接提供操作系統調度命令park,unpark,減少信號量的開銷,提高新能。

             從上面可以看出,Unsafe類是通過提供底層的操作系統命令接口給開發者,從而提供程序的性能。



          posted on 2015-03-15 23:42 abin 閱讀(1814) 評論(0)  編輯  收藏 所屬分類: concurrent
          主站蜘蛛池模板: 房产| 东乌珠穆沁旗| 广水市| 哈巴河县| 双江| 富民县| 松原市| 贵州省| 松江区| 红安县| 昌吉市| 密山市| 南城县| 册亨县| 洛川县| 拜城县| 天津市| 壶关县| 云林县| 兰州市| 临泽县| 波密县| 商丘市| 当阳市| 营口市| 乌兰浩特市| 双鸭山市| 崇仁县| 兴安盟| 工布江达县| 贵南县| 大冶市| 徐汇区| 镇远县| 邢台市| 新民市| 平阴县| 临沭县| 科尔| 朝阳县| 泗阳县|