`
wx1568520008
  • 浏览: 20392 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Java中Unsafe类详解

 
阅读更多

java不能直接访问操作系统底层,而是通过本地方法来访问。Unsafe类提供了硬件级别的原子操作,主要提供了以下功能:

1、通过Unsafe类可以分配内存,可以释放内存;

类中提供的3个本地方法allocateMemory、reallocateMemory、freeMemory分别用于分配内存,扩充内存和释放内存,与C语言中的3个方法对应。

public native long allocateMemory(long l);
public native long reallocateMemory(long l, long l1);
public native void freeMemory(long l);

2、可以定位对象某字段的内存位置,也可以修改对象的字段值,即使它是私有的;

字段的定位:

JAVA中对象的字段的定位可能通过staticFieldOffset方法实现,该方法返回给定field的内存地址偏移量,这个值对于给定的filed是唯一的且是固定不变的。

getIntVolatile方法获取对象中offset偏移地址对应的整型field的值,支持volatile load语义。

getLong方法获取对象中offset偏移地址对应的long型field的值

数组元素定位:

Unsafe类中有很多以BASE_OFFSET结尾的常量,比如ARRAY_INT_BASE_OFFSET,ARRAY_BYTE_BASE_OFFSET等,这些常量值是通过arrayBaseOffset方法得到的。arrayBaseOffset方法是一个本地方法,可以获取数组第一个元素的偏移地址。Unsafe类中还有很多以INDEX_SCALE结尾的常量,比如 ARRAY_INT_INDEX_SCALE , ARRAY_BYTE_INDEX_SCALE等,这些常量值是通过arrayIndexScale方法得到的。arrayIndexScale方法也是一个本地方法,可以获取数组的转换因子,也就是数组中元素的增量地址。将arrayBaseOffset与arrayIndexScale配合使用,可以定位数组中每个元素在内存中的位置。

Arrays和Java别的对象一样,都有一个对象头,它是存储在实际的数据前面的。这个头的长度可以通过unsafe.arrayBaseOffset(T[].class)方法来获取到,这里T是数组元素的类型。数组元素的大小可以通过unsafe.arrayIndexScale(T[].class) 方法获取到。这也就是说要访问类型为T的第N个元素的话,你的偏移量offset应该是arrayOffset+N*arrayScale。

public final class Unsafe {
    public static final int ARRAY_INT_BASE_OFFSET;
    public static final int ARRAY_INT_INDEX_SCALE;

    public native long staticFieldOffset(Field field);
    public native int getIntVolatile(Object obj, long l);
    public native long getLong(Object obj, long l);
    public native int arrayBaseOffset(Class class1);
    public native int arrayIndexScale(Class class1);

    static 
    {
        ARRAY_INT_BASE_OFFSET = theUnsafe.arrayBaseOffset([I);
        ARRAY_INT_INDEX_SCALE = theUnsafe.arrayIndexScale([I);
    }
}

3、挂起与恢复

将一个线程进行挂起是通过park方法实现的,调用 park后,线程将一直阻塞直到超时或者中断等条件出现。unpark可以终止一个挂起的线程,使其恢复正常。整个并发框架中对线程的挂起操作被封装在 LockSupport类中,LockSupport类中有各种版本pack方法,但最终都调用了Unsafe.park()方法。

 

public class LockSupport {
    public static void unpark(Thread thread) {
        if (thread != null)
            unsafe.unpark(thread);
    }

    public static void park(Object blocker) {
        Thread t = Thread.currentThread();
        setBlocker(t, blocker);
        unsafe.park(false, 0L);
        setBlocker(t, null);
    }

    public static void parkNanos(Object blocker, long nanos) {
        if (nanos > 0) {
            Thread t = Thread.currentThread();
            setBlocker(t, blocker);
            unsafe.park(false, nanos);
            setBlocker(t, null);
        }
    }

    public static void parkUntil(Object blocker, long deadline) {
        Thread t = Thread.currentThread();
        setBlocker(t, blocker);
        unsafe.park(true, deadline);
        setBlocker(t, null);
    }

    public static void park() {
        unsafe.park(false, 0L);
    }

    public static void parkNanos(long nanos) {
        if (nanos > 0)
            unsafe.park(false, nanos);
    }

    public static void parkUntil(long deadline) {
        unsafe.park(true, deadline);
    }
}

 

4、CAS操作

是通过compareAndSwapXXX方法实现的

 

/**
* 比较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操作有3个操作数,内存值M,预期值E,新值U,如果M==E,则将内存值修改为B,否则啥都不做。

转载于:https://my.oschina.net/u/2365905/blog/1802195

分享到:
评论

相关推荐

    Java 多线程与并发(8-26)-JUC原子类- CAS, Unsafe和原子类详解.pdf

    Java多线程与并发处理是Java编程中的高级话题,涉及到JUC(java.util.concurrent)包中的原子类、CAS(Compare-And-Swap)机制、Unsafe类以及多线程并发的无锁方案和线程安全的实现方法。 CAS是一种无锁的同步机制...

    Java并发编程之LockSupport、Unsafe详解.docx

    在Java并发编程中,LockSupport和Unsafe是两个关键的工具类,它们提供了底层的线程控制功能,使得开发者能够深入地管理和控制线程的行为。LockSupport是Java并发库中的一个核心工具类,它提供了线程的阻塞和唤醒功能...

    Java中的魔法类:sun.misc.Unsafe示例详解

    Java中的`sun.misc.Unsafe`类是一个特殊的存在,它提供了对Java语言规范之外的底层操作的访问。这个类主要用于优化性能和实现一些JVM级别的功能,但同时也因为其潜在的安全风险和不稳定因素,通常不推荐在常规编程中...

    【Java学习+面试指南】 一份涵盖大部分Java程序员所需要掌握的核心知识

    Java 魔法类 Unsafe 详解 Java SPI 机制详解 Java 语法糖详解 集合 知识点/面试题总结: Java 集合常见知识点&面试题总结(上) (必看 ) Java 集合常见知识点&面试题总结(下) (必看 ) Java 容器使用注意事项总结 源码...

    「Java学习+面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识 准备 Java 面试,首选.zip

    Java 魔法类 Unsafe 详解 Java SPI 机制详解 Java 语法糖详解 集合 知识点/面试题总结 : Java 集合常见知识点&面试题总结(上) (必看 ) Java 集合常见知识点&面试题总结(下) (必看 ) Java 容器使用注意事项总结 ...

    「Java学习+面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识

    Java 魔法类 Unsafe 详解 Java SPI 机制详解 Java 语法糖详解 集合 知识点/面试题总结: Java 集合常见知识点&面试题总结(上) (必看 ) Java 集合常见知识点&面试题总结(下) (必看 ) Java 容器使用注意事项总结 源码...

    Java并发编程学习之Unsafe类与LockSupport类源码详析

    《深入解析Java并发编程:Unsafe类与LockSupport类源码剖析》 在Java并发编程领域,Unsafe类和LockSupport类是两个重要的底层工具类,它们提供了低级别的内存操作和线程控制,使得开发者能够实现高效的并发算法和...

    Zookeeper Api(java)入门详解与应用场景

    **Zookeeper API(Java)入门详解** Zookeeper是一款分布式协调服务,由Apache基金会开发,它为分布式应用提供一致性服务,包括命名服务、配置管理、集群同步、分布式锁等。在Java开发中,我们通常会使用Zookeeper...

    JUC基石——Unsafe类

    在Java并发编程领域,`Unsafe`类扮演着一个特殊的角色,尽管它被标记为“不安全”,但却是Java并发库(JUC)中的重要基石,尤其在高并发场景下,如`ConcurrentHashMap`、`Atomic`系列类、`AQS`...

    Java CAS底层实现原理实例详解

    在 Java 中,CAS 操作主要在 JUC 中的 atomic 包,通过 Unsafe 类实现。Unsafe 类提供了一系列增加 Java 语言能力的操作,如内存管理、操作类/对象/变量、多线程同步等。Unsafe 类中的方法都是 native 方法,由 JVM ...

    Java 多线程与并发(15-26)-JUC集合- ConcurrentLinkedQueue详解.pdf

    ### Java多线程与并发(15-26)-JUC集合-ConcurrentLinkedQueue详解 #### 一、ConcurrentLinkedQueue概述 `ConcurrentLinkedQueue`是Java实用工具包(J.U.C)中的一个高性能线程安全队列,主要用于解决多线程环境下...

    Java AtomicInteger类的使用方法详解

    Java AtomicInteger类的使用方法详解 Java AtomicInteger类是Java中提供的一种原子操作的Integer类,通过线程安全的方式操作加减。它可以在高并发情况下使用,提供原子操作来进行Integer的使用。 Atomicinteger类...

    java面向对象之JVM创建及分配策略方法详解.docx

    - **Unsafe.allocateInstance**:在特定情况下,可以使用sun.misc.Unsafe类的allocateInstance()方法直接在堆上创建对象,但这通常是不推荐的,因为它绕过了常规的构造函数调用。 2. **对象的创建过程** 创建一个...

    1java锁与并发与线程池.doc

    - **Unsafe**是Java中的一个内部类,提供了对内存操作的直接访问,包括对象字段的读写和内存分配等。由于其潜在的风险,通常只在高级并发优化或者框架中使用。 - 获取Unsafe实例通常需要反射,或者通过特定的系统...

    Java 多线程与并发(9-26)-JUC锁- LockSupport详解.pdf

    LockSupport是Java中用于多线程同步的一个工具类,它提供了一组基础的线程阻塞和解除阻塞的方法。这个类位于java.util.concurrent.locks包下,是实现并发编程中AQS(AbstractQueuedSynchronizer)框架的重要基础之一...

    Java操作Zookeeper原理及过程详解

    Java操作Zookeeper是一种常见的在分布式环境中管理和协调数据的方法。Zookeeper作为一个分布式协调服务,提供了诸如数据发布/订阅、命名服务、分布式锁等关键功能。在Java应用中,我们可以使用Zookeeper的客户端API...

    JDK1.6源码 JAVA

    例如,`java.lang.ClassLoader`类负责加载类文件,`java.lang.Thread`类实现了线程的创建和管理,而`java.lang.Runtime`则提供了与操作系统交互的接口。 2. **编译器** JDK1.6的编译器`javac`的源码可以让我们了解...

    04 并发编程专题01.zip

    在Java并发编程中,"Atomic&Unsafe魔法类详解"是一个重要的主题,这通常涉及到Java并发库中的两个核心类:`Atomic`系列类和`Unsafe`类。这些类提供了高效、低级别的原子操作,用于实现线程安全的数据共享,是多线程...

    The java.util.concurrent Synchronizer Framework

    - **原子性操作**:通过使用Unsafe类中的CAS操作来实现对`state`变量的原子性操作,减少锁的竞争。 - **自旋等待**:对于那些即将获得锁的线程,AQS采用了自旋等待策略,避免频繁的线程上下文切换。 - **公平性与非...

Global site tag (gtag.js) - Google Analytics