Unsafe例子
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例子的更多相关文章
- CSharpGL(25)一个用raycast实现体渲染VolumeRender的例子
CSharpGL(25)一个用raycast实现体渲染VolumeRender的例子 本文涉及的VolumeRendering相关的C#代码是从(https://github.com/toolchai ...
- unsafe
今天无意中发现C#这种完全面向对象的高级语言中也可以用不安全的指针类型,即要用到unsafe关键字.在公共语言运行库 (CLR) 中,不安全代码是指无法验证的代码.C# 中的不安全代码不一定是危险的, ...
- 【实战Java高并发程序设计 1】Java中的指针:Unsafe类
是<实战Java高并发程序设计>第4章的几点. 如果你对技术有着不折不挠的追求,应该还会特别在意incrementAndGet() 方法中compareAndSet()的实现.现在,就让我 ...
- C#+无unsafe的非托管大数组(large unmanaged array in c# without 'unsafe' keyword)
C#+无unsafe的非托管大数组(large unmanaged array in c# without 'unsafe' keyword) +BIT祝威+悄悄在此留下版了个权的信息说: C#申请一 ...
- CSharpGL(1)从最简单的例子开始使用CSharpGL
CSharpGL(1)从最简单的例子开始使用CSharpGL 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo ...
- c中使用gets() 提示warning: this program uses gets(), which is unsafe.
今天在C代码中使用gets()时提示“warning: this program uses gets(), which is unsafe.”,然后这个程序还能运行,无聊的我开始查阅资料,为啥gets ...
- sun.misc.Unsafe的理解
以下sun.misc.Unsafe源码和demo基于jdk1.7: 最近在看J.U.C里的源码,很多都用到了sun.misc.Unsafe这个类,一知半解,看起来总感觉有点不尽兴,所以打算对Unsaf ...
- Unsafe与CAS
Unsafe 简单讲一下这个类.Java无法直接访问底层操作系统,而是通过本地(native)方法来访问.不过尽管如此,JVM还是开了一个后门,JDK中有一个类Unsafe,它提供了硬件级别的原子操作 ...
- Java为什么会引入及如何使用Unsafe
综述 sun.misc.Unsafe至少从2004年Java1.4开始就存在于Java中了.在Java9中,为了提高JVM的可维护性,Unsafe和许多其他的东西一起都被作为内部使用类隐藏起来了.但是 ...
随机推荐
- java 的11个特性
以下11个特性来自于著名的"java白皮书"中,博主会针对这些特性一一进行粗略的解释.相信看完博主的这篇文章,以后在和小伙伴们吹牛逼,可就有了切实可靠的理论依据了. 11个特性分别 ...
- 在使用 Fortify进行源码扫描时需要做对项目需要做什么?
1.一般我们的项目都是svn 或git 进行管理的,为了扫出异常的问题 做好把 “” .svn “” 文件删除 2.把我们的项目需要的jar 文件放到一个文件夹内同项目一起进行扫描.这样为 ...
- mysql Waiting for table flush
应用突然被hang住了,tomcat日志报错,所有涉及到数据库的操作都报错,卡死. show processlist 查看到大量的:Waiting for table flush 应该是 进行了 dd ...
- linux 的 expect 自动交互
https://www.jianshu.com/p/0194cbd70d39 https://www.cnblogs.com/saneri/p/10819348.html 参考 expect是一个自 ...
- Java面试题:JVM中的类加载机制
JVM 的类加载机制是指 JVM 把描述类的数据从 .class 文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这就是 JVM 的类加载机制. 类 ...
- 【洛谷P3749】[六省联考2017]寿司餐厅(网络流)
洛谷 题意: 给出\(n\)份寿司,现可以选取任意多次连续区间内的寿司,对于区间\([l,r]\),那么贡献为\(\sum_{i=l}^r \sum_{j=i}^rd_{i,j}\)(对于相同的\(d ...
- 老男孩LINUX--打包压缩、查看、解压
tar就是打包的意思,打包就是将多个文件或者目录放置到一起,整体的大小没有变化,tar可以调用一些压缩的软件,比如zip,在打包的同时进行压缩.先来上一个例子: tar zcvf /tmp/etc.t ...
- django学习-管理界面、视图
django管理界面 设计背景 为你的员工或客户生成一个用户添加,修改和删除内容的后台是一项缺乏创造性和乏味的工作.因此,django全自动地根据模型创建后台界面. django产生于一个公众页面和内 ...
- CentOS 8 正式发布!
CentOS 8 正式发布! CentOS 8 和 RedHat Enterprise Linux 8 发行的版本是一致的,都是基于 Fedora 28 和 内核 4.18.支持传统的.新兴的工作负载 ...
- 莫烦TensorFlow_07 tensorboard可视化
import tensorflow as tf import numpy as np import matplotlib.pyplot as plt def add_layer(inputs, in_ ...