Unsafe例子
2024-08-27 22:36:13
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 ");
}
} }
最新文章
- Greenplum 源码安装教程 —— 以 CentOS 平台为例
- Linux find命令的用法实践
- DB2数据库参数建议(Linux)
- 【学】React的学习之旅6-组件的嵌套2
- Android4.4 以太网和DHCP启动过程介绍
- PHP+jQuery 注册模块的改进之二:激活链接的URL设置与有效期
- Spring配置文件解析--集合注入方法
- HtmlPrefixScopeExtensions
- java中进程与线程的三种实现方式
- Android-ViewPagerIndicator框架使用——TabPageIndicator以及样式的修改
- solr-tomcat 中文乱码
- android开发之---文字居中---android中去掉标题栏
- Maven使用第三方jar文件的两种方法 转
- 自定义UITableView的Seperator
- linux 获取cpu百分比
- POJ 2175 Evacuation Plan (费用流,负环,消圈法,SPFA)
- C - Big Number
- 在centos7中python3的安装注意
- vue脚手架搭建移动端项目--flexible.js
- Groovy 设计模式 -- 装饰器模式
热门文章
- asp.net 获取当前,相对,绝对路径
- VUE-父组件和子组件
- PowerShell美化
- 远程唤醒、WOL、Magic_Packet【转】
- NLP中的预训练语言模型(四)—— 小型化bert(DistillBert, ALBERT, TINYBERT)
- CMS收集器和G1收集器 他们的优缺点对比 G1只有并发标记才不会stop-the-world 其他都会停下来(阿里多次问到)
- C++和C的相互调用
- 解析YAML文件
- 201871010104-陈园园 《面向对象程序设计(java)》第十二周学习总结
- 201871010110-李华《面向对象程序设计(java)》第十三周学习总结