在看 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是一門安全的編程語言,防止程序員犯很多愚蠢的錯誤,它們大部分是基于內存管理的。但是,有一種方式可以有意的執行一些不安全、容易犯錯的操作,那就是使用
CAS操作有3個操作數,內存值M,預期值E,新值U,如果M==E,則將內存值修改為B,否則啥都不做。
sun.misc.Unsafe這個類是如此地不安全,以至于JDK開發者增加了很多特殊限制來訪問它。它的構造器是私有的,工廠方法getUnsafe()的調用器只能被Bootloader加載。如你在下面代碼片段的第8行所見,這個家伙甚至沒有被任何類加載器加載,所以它的類加載器是null。它會拋出SecurityException 異常來阻止侵入者。
public final class Unsafe {
幾句關于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/)
幸運的是這里有一個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一些有用的特性
- 虛擬機“集約化”(VM intrinsification):如用于無鎖Hash表中的CAS(比較和交換)。再比如compareAndSwapInt這個方法用JNI調用,包含了對CAS有特殊引導的本地代碼。在這里你能讀到更多關于CAS的信息:http://en.wikipedia.org/wiki/Compare-and-swap。
- 主機虛擬機(譯注:主機虛擬機主要用來管理其他虛擬機。而虛擬平臺我們看到只有guest VM)的sun.misc.Unsafe功能能夠被用于未初始化的對象分配內存(用allocateInstance方法),然后將構造器調用解釋為其他方法的調用。
- 你可以從本地內存地址中追蹤到這些數據。使用java.lang.Unsafe類獲取內存地址是可能的。而且可以通過unsafe方法直接操作這些變量!
- 使用allocateMemory方法,內存可以被分配到堆外。例如當allocateDirect方法被調用時DirectByteBuffer構造器內部會使用allocateMemory。
- arrayBaseOffset和arrayIndexScale方法可以被用于開發arraylets,一種用來將大數組分解為小對象、限制掃描的實時消耗或者在大對象上做更新和移動。
Unsafe.java是jdk并發類庫java.util.concurrent包中使用的底層類,該類中的方法都是通過native方法調用操作系統命令。