设为首页 加入收藏

TOP

Java不能操作内存?Unsafe了解一下(七)
2023-08-26 21:11:18 】 浏览:126
Tags:Java 能操作 Unsafe 解一下
到其他线程调用了unpark这个线程才会结束阻塞 // 一般像这种无限期等待的调了多少次park(false, 0)就要对于调同样次数的unpark才会完全解除阻塞 unsafe.park(false, 0); }

输出:

2020-05-11 08:01:04 main is running...
2020-05-11 08:01:10 main continue...
2020-05-11 08:01:13 main continue...

再看一个案例:

public void test6() throws Exception {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                System.out.println(LocalDateTime.now().format(formatter) + " " + Thread.currentThread().getName()
                    + " is running...");
                // 这里让当前线程阻塞600s也就是10分钟,注意:如果park第一个参数是true的话,表示绝对时间,这个时间是毫秒级的,也就是系统时间,系统到这个绝对时间后才唤醒执行
                unsafe.park(true, System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(600));
                System.out.println(LocalDateTime.now().format(formatter) + " " + Thread.currentThread().getName()
                    + " continue...");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                System.out.println(LocalDateTime.now().format(formatter) + " " + Thread.currentThread().getName()
                    + " is running...");
                // 这里让当前线程阻塞600s也就是10分钟,注意:如果park第一个参数是true的话,表示绝对时间,这个时间是毫秒级的,也就是系统时间,系统到这个绝对时间后才唤醒执行
                unsafe.park(true, System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(600));
                // unsafe.park(true, System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(600));
                System.out.println(LocalDateTime.now().format(formatter) + " " + Thread.currentThread().getName()
                    + " continue...");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    t1.start();
    t2.start();
    // 主线程休眠2秒
    Thread.sleep(2000);
    System.out
        .println(LocalDateTime.now().format(formatter) + " " + Thread.currentThread().getName() + " is running...");
    // 这里调了unpark方法,参数就是t1线程,unsafe.unpark唤醒了t1线程,使得t1线程不用等到10分钟立马就可以执行
    unsafe.unpark(t1);
    // 下面连续调用了两次unpark t2线程,但是结果只释放了一次令牌,如果把t2线程的unsafe.park注释去掉,那么t2线程会一直等到park的时间到后被唤醒执行,
    unsafe.unpark(t2);
    unsafe.unpark(t2);
    System.out.println(LocalDateTime.now().format(formatter) + " " + Thread.currentThread().getName() + " over...");
}

输出如下:

2020-05-11 08:05:26 Thread-1 is running...
2020-05-11 08:05:26 Thread-0 is running...
2020-05-11 08:05:28 main is running...
2020-05-11 08:05:28 main over...
2020-05-11 08:05:28 Thread-1 continue...
2020-05-11 08:05:28 Thread-0 continue...

unsafe的park和unpark在JUC并发包下使用的特别多,后续再介绍吧

内存屏障

这个我没有深入的了解,网上找了些资料看了看,没有具体的实践过,大家可以了解下。

loadFence:保证在这个屏障之前的所有读操作都已经完成。
storeFence:保证在这个屏障之前的所有写操作都已经完成。
fullFence:保证在这个屏障之前的所有读写操作都已经完成。

其他

类加载,类实例化相关的一些方法,还有其他的方法,这里不再一一说明,虽然不常用,但是了解其运行原理,或者去研究一下jvm的源码对自己都是一种提升。

再见

好了,就胡扯到这里吧,文章里的都是个人理解和实践,难免会有理解错误和实践错误的,请各位看官多多指正。

首页 上一页 4 5 6 7 下一页 尾页 7/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇10、Spring之AOP概述 下一篇new ArrayList 不当导致 CPU 飙升..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目