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 ");
}
} }

最新文章

  1. Greenplum 源码安装教程 —— 以 CentOS 平台为例
  2. Linux find命令的用法实践
  3. DB2数据库参数建议(Linux)
  4. 【学】React的学习之旅6-组件的嵌套2
  5. Android4.4 以太网和DHCP启动过程介绍
  6. PHP+jQuery 注册模块的改进之二:激活链接的URL设置与有效期
  7. Spring配置文件解析--集合注入方法
  8. HtmlPrefixScopeExtensions
  9. java中进程与线程的三种实现方式
  10. Android-ViewPagerIndicator框架使用——TabPageIndicator以及样式的修改
  11. solr-tomcat 中文乱码
  12. android开发之---文字居中---android中去掉标题栏
  13. Maven使用第三方jar文件的两种方法 转
  14. 自定义UITableView的Seperator
  15. linux 获取cpu百分比
  16. POJ 2175 Evacuation Plan (费用流,负环,消圈法,SPFA)
  17. C - Big Number
  18. 在centos7中python3的安装注意
  19. vue脚手架搭建移动端项目--flexible.js
  20. Groovy 设计模式 -- 装饰器模式

热门文章

  1. asp.net 获取当前,相对,绝对路径
  2. VUE-父组件和子组件
  3. PowerShell美化
  4. 远程唤醒、WOL、Magic_Packet【转】
  5. NLP中的预训练语言模型(四)—— 小型化bert(DistillBert, ALBERT, TINYBERT)
  6. CMS收集器和G1收集器 他们的优缺点对比 G1只有并发标记才不会stop-the-world 其他都会停下来(阿里多次问到)
  7. C++和C的相互调用
  8. 解析YAML文件
  9. 201871010104-陈园园 《面向对象程序设计(java)》第十二周学习总结
  10. 201871010110-李华《面向对象程序设计(java)》第十三周学习总结