java unsafe cas_java并发Unsafe和CAS

Unsafe提供了一些可以直接操控内存和线程的底层操作。被JDK广泛应用于java.nio和并发包等实现中,但是不建议在生产环境中使用。

如何使用:

Unsafe类是如此地不安全,以至于JDK开发者增加了很多特殊限制来访问它。

1、私有的构造器

2、工厂方法getUnsafe()的调用器只能被Bootloader加载,否则抛出SecurityException 异常

但是我们可以通过反射获取Unsafe的实例

public static Unsafe getUnsafe() {

try {

Field f = Unsafe.class.getDeclaredField("theUnsafe");

f.setAccessible(true);

return (Unsafe)f.get(null);

} catch (Exception e) {

/* ... */

}

}

看Future.java源码是如何使用Unsafe的

private volatile int state;

private volatile Thread runner;

private volatile WaitNode waiters;

// Unsafe mechanics

private static final sun.misc.Unsafe UNSAFE;

private static final long stateOffset;

private static final long runnerOffset;

private static final long waitersOffset;

static {

try {

// 获取UNSAFE 的实例

UNSAFE = sun.misc.Unsafe.getUnsafe();

Class> k = FutureTask.class;

// 获取state字段的偏移量

stateOffset = UNSAFE.objectFieldOffset

(k.getDeclaredField("state"));

runnerOffset = UNSAFE.objectFieldOffset

(k.getDeclaredField("runner"));

waitersOffset = UNSAFE.objectFieldOffset

(k.getDeclaredField("waiters"));

} catch (Exception e) {

throw new Error(e);

}

}

一些有用的api:

1、objectFieldOffset:获取指定的对象实例变量在对象内存中的偏移量

long stateOffset = UNSAFE.objectFieldOffset

(FutureTask.class.getDeclaredField("state"));

2、compareAndSwapInt:通过比较并替换的机制,修改指定偏移量内存的值

判断内存值stateOffset和期望值expectValue是否一致,一致就修改为新值newValue并返回true,不一致就返回false

UNSAFE.compareAndSwapInt(this, stateOffset, expectValue, newValue)

3、park:使当前线程睡眠

// LockSupport工具类

LockSupport.park(this);

LockSupport.parkNanos(this, nanos);

public static void park(Object blocker) {

Thread t = Thread.currentThread();

setBlocker(t, blocker);

UNSAFE.park(false, 0L);

setBlocker(t, null);

}

4、unpark:唤醒某个睡眠线程

LockSupport.unpark(thread);

public static void unpark(Thread thread) {

if (thread != null)

UNSAFE.unpark(thread);

}

CAS:

CAS(Compare and Swap),即比较并替换,实现并发算法时常用到的一种技术,Doug lea大神在java同步器中大量使用了CAS技术,鬼斧神工的实现了多线程执行的安全性。

CAS的思想很简单:三个参数,一个当前内存值V、旧的预期值A、即将更新的值B,当且仅当预期值A和内存值V相同时,将内存值修改为B并返回true,否则什么都不做,并返回false。

缺点:

CAS存在一个很明显的问题,即ABA问题。

如果变量V初次读取的时候是A,并且在准备赋值的时候检查到它仍然是A,那能说明它的值没有被其他线程修改过了吗?

如果在这段期间曾经被改成B,然后又改回A,那CAS操作就会误认为它从来没有被修改过。针对这种情况,java并发包中提供了一个带有标记的原子引用类AtomicStampedReference,它可以通过控制变量值的版本来保证CAS的正确性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值