Java和C++语言的一个重要区别就是Java中我们无法直接操作一块内存区域,不能像C++中那样可以自己申请内存和释放内存。Java中的Unsafe类为我们提供了类似C++手动管理内存的能力,不建议使用该类

(1)Unsafe对int,long ,Object的CAS操作

public class UnsafeTest {

    public static void main(String[] args) throws Exception {
ExecutorService service = Executors.newFixedThreadPool();
Counter counter = new CASCounter();
long start = System.currentTimeMillis();
for (int i = ; i < ; i++) {
service.submit(new CounterRunnable(counter, ));
}
service.shutdown();
service.awaitTermination(, TimeUnit.HOURS);
System.out.println("counter : " + counter.getCount());
System.out.println("time elapse : " + (System.currentTimeMillis() - start)); } public static Unsafe getUnsafe() throws IllegalAccessException {
Field unsafeField = Unsafe.class.getDeclaredFields()[];
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.get(null);
return unsafe;
} interface Counter {
void increment(); long getCount();
} static class StupidCounter implements Counter { private long value = ; @Override
public void increment() {
value++;
} @Override
public long getCount() {
return value;
} } static class SynCounter implements Counter { private long value = ; @Override
public synchronized void increment() {
value++;
} @Override
public long getCount() {
return value;
} } static class LockCounter implements Counter { private long value = ; private Lock lock = new ReentrantLock(); @Override
public void increment() {
lock.lock();
try {
value++;
} finally {
lock.unlock();
}
} @Override
public long getCount() {
return value;
} } static class AtomicCounter implements Counter { private AtomicLong value = new AtomicLong(); @Override
public void increment() {
value.incrementAndGet();
} @Override
public long getCount() {
return value.get();
} } static class CASCounter implements Counter { private Unsafe unsafe;
private long offset;
private volatile long value = ; CASCounter() throws Exception {
unsafe = getUnsafe();
offset = unsafe.objectFieldOffset(CASCounter.class.getDeclaredField("value"));
} @Override
public void increment() {
long current = value;
while (!unsafe.compareAndSwapLong(this, offset, value, value + )) {
current = value;
}
} @Override
public long getCount() {
return value;
} } static class CounterRunnable implements Runnable {
Counter counter;
int num; CounterRunnable(Counter counter, int num) {
this.counter = counter;
this.num = num;
} @Override
public void run() {
for (int i = ; i < num; i++) {
counter.increment();
}
}
} }

(2)可以绕过构造函数实例化对象

public class UnsafePlayer {

    // 通过反射实例化Unsafe
public static Unsafe getUnsafe() throws IllegalAccessException {
Field unsafeField = Unsafe.class.getDeclaredFields()[];
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.get(null);
return unsafe;
} public static void main(String[] args) throws Exception {
// 获取Unsafe
Unsafe unsafe = getUnsafe();
// 实例化Player
Player player = (Player) unsafe.allocateInstance(Player.class);
player.setName("li lei");
System.out.println(player.getName());
}
} class Player {
private String name; private Player() { } public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

(3)直接修改内存的值

/**
*
* 直接修改了Foo对象的current值
*/
public class UnsafeTest2 { // 通过反射实例化Unsafe
public static Unsafe getUnsafe() throws IllegalAccessException {
Field unsafeField = Unsafe.class.getDeclaredFields()[];
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.get(null);
return unsafe;
} public static void main(String[] args) throws Exception {
Foo foo = new Foo();
Unsafe unsafe = getUnsafe();
Field field = Foo.class.getDeclaredField("current");
unsafe.putInt(foo, unsafe.objectFieldOffset(field), );
foo.work();
}
} class Foo { private int current = ; public void work() {
if (current == ) {
System.out.println(" I am working ");
}
} }

Unsafe例子的更多相关文章

  1. CSharpGL(25)一个用raycast实现体渲染VolumeRender的例子

    CSharpGL(25)一个用raycast实现体渲染VolumeRender的例子 本文涉及的VolumeRendering相关的C#代码是从(https://github.com/toolchai ...

  2. unsafe

    今天无意中发现C#这种完全面向对象的高级语言中也可以用不安全的指针类型,即要用到unsafe关键字.在公共语言运行库 (CLR) 中,不安全代码是指无法验证的代码.C# 中的不安全代码不一定是危险的, ...

  3. 【实战Java高并发程序设计 1】Java中的指针:Unsafe类

    是<实战Java高并发程序设计>第4章的几点. 如果你对技术有着不折不挠的追求,应该还会特别在意incrementAndGet() 方法中compareAndSet()的实现.现在,就让我 ...

  4. C#+无unsafe的非托管大数组(large unmanaged array in c# without 'unsafe' keyword)

    C#+无unsafe的非托管大数组(large unmanaged array in c# without 'unsafe' keyword) +BIT祝威+悄悄在此留下版了个权的信息说: C#申请一 ...

  5. CSharpGL(1)从最简单的例子开始使用CSharpGL

    CSharpGL(1)从最简单的例子开始使用CSharpGL 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo ...

  6. c中使用gets() 提示warning: this program uses gets(), which is unsafe.

    今天在C代码中使用gets()时提示“warning: this program uses gets(), which is unsafe.”,然后这个程序还能运行,无聊的我开始查阅资料,为啥gets ...

  7. sun.misc.Unsafe的理解

    以下sun.misc.Unsafe源码和demo基于jdk1.7: 最近在看J.U.C里的源码,很多都用到了sun.misc.Unsafe这个类,一知半解,看起来总感觉有点不尽兴,所以打算对Unsaf ...

  8. Unsafe与CAS

    Unsafe 简单讲一下这个类.Java无法直接访问底层操作系统,而是通过本地(native)方法来访问.不过尽管如此,JVM还是开了一个后门,JDK中有一个类Unsafe,它提供了硬件级别的原子操作 ...

  9. Java为什么会引入及如何使用Unsafe

    综述 sun.misc.Unsafe至少从2004年Java1.4开始就存在于Java中了.在Java9中,为了提高JVM的可维护性,Unsafe和许多其他的东西一起都被作为内部使用类隐藏起来了.但是 ...

随机推荐

  1. Try-Catch-Finally语句块执行问题

    Try-Catch-Finally语句块执行问题 记录一个今天某公司的面试问题,其实我问题回答对了,但是面试官问我动手验证过没有,这还真没有,纯理论,被怼惨了,希望自己能变得更强大. Try-Catc ...

  2. 处理 JS中 undefined 的 7 个技巧

    摘要: JS的大部分报错都是undefined... 作者:前端小智 原文:处理 JS中 undefined 的 7 个技巧 Fundebug经授权转载,版权归原作者所有. 大约8年前,当原作者开始学 ...

  3. 关与 @EnableConfigurationProperties 注解

    @EnableConfigurationProperties注解的作用是: 让使用 @ConfigurationProperties 注解的类生效. 当@EnableConfigurationProp ...

  4. MongoDB 4.X 用户和角色权限管理总结

    关于MongoDB的用户和角色权限的梳理一直不太清晰,仔细阅读了下官方文档,并对此做个总结. 默认情况下,MongoDB实例启动运行时是没有启用用户访问权限控制的,也就是说,在实例本机服务器上都可以随 ...

  5. Centos 7 修改网卡名称、静态IP

    修改内核选项 # vim /etc/sysconfig/grub GRUB_TIMEOUT= GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc ...

  6. django rest framework 过滤 lim分页

    一.过滤 1.首先引用diango 自带的过滤配置 2.导入模块 from django_filters.rest_framework import DjangoFilterBackend from ...

  7. C#实体类(复杂类)与XML互相转换

    实体类转换成XML方法: 将实体类转换成XML需要使用XmlSerializer类的Serialize方法,将实体类序列化 public static string XmlSerialize<T ...

  8. 免费音乐播放器-airplay(网上收集,仅供学习与研究,支持正版)

    AirPlay媒体播放器无需安装,并不会修改注册表,生成桌面快捷方式,加入启动菜单及快速启动. 因此,您只需要下载本软件,保存在任何地方即可使用.使用方便,界面酷炫. 自动下载和显示歌词.专辑封面.汇 ...

  9. 重新学习SpringMVC——高级

    30. SpringMVC_RESTRUL_CRUD_显示所有员工信息31. SpringMVC_RESTRUL_CRUD_添加操作&表单标签32. SpringMVC_RESTRUL_CRU ...

  10. python27期day06:小数据池、深浅拷贝、集合、作业题。

    0.pycharm是代码块.黑窗口是小数据池.如下图: 1.驻留机制(长得像的共用一个内存地址)分小数据池缓存机制:后期开发时能明确知道.为什么不能正常使用.把经常用的东西放入规则(黑窗口)里. 数字 ...