设为首页 加入收藏

TOP

Java不能操作内存?Unsafe了解一下(六)
2023-08-26 21:11:18 】 浏览:127
Tags:Java 能操作 Unsafe 解一下
ct var1);

我们先看看monitor同步相关的测试:

public void test4() {
    Object obj = new Object();
    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                System.out.println(Thread.currentThread().getName() + " isrunning...");
                unsafe.monitorEnter(obj);
                System.out.println(Thread.currentThread().getName() + " got monitorEnter...");
                Thread.sleep(3000);
                System.out.println(Thread.currentThread().getName() + " business over...");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                unsafe.monitorExit(obj);
                System.out.println(Thread.currentThread().getName() + " monitorExit...");
            }
        }
    });
    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                System.out.println(Thread.currentThread().getName() + " isrunning...");
                unsafe.monitorEnter(obj);
                System.out.println(Thread.currentThread().getName() + " got monitorEnter...");
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() + " business over...");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                unsafe.monitorExit(obj);
                System.out.println(Thread.currentThread().getName() + " monitorExit...");
            }
        }
    });
    Thread t3 = new Thread(new Runnable() {
        @Override
        public void run() {
            boolean flag = false;
            try {
                System.out.println(Thread.currentThread().getName() + " isrunning...");
                flag = unsafe.tryMonitorEnter(obj);
                System.out.println(Thread.currentThread().getName() + " tryMonitorEnter:" + flag);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (flag) {
                    unsafe.monitorExit(obj);
                    System.out.println(Thread.currentThread().getName() + " monitorExit...");
                }
            }
            System.out.println(Thread.currentThread().getName() + " over...");
        }
    });
    t1.start();
    t2.start();
    t3.start();
}

可能的一种输出如下(线程是根据系统分配资源调度的,输出先后顺序会有多种),下面的这个输出我们可以看到先输出3个线程都启动了,Thread-2尝试获取锁失败就结束了,然后Thread-0竞争到了对象锁,等Thread-0线程运行完毕释放了锁,Thread-1才会获取到锁继续执行直到结束释放锁。
Tips:

monitor相关的方法已经加了@deprecated注解,官方已经不再建议使用,可以换成其他锁或者同步方式

Thread-0 isrunning...
Thread-2 isrunning...
Thread-2 tryMonitorEnter:false
Thread-2 over...
Thread-1 isrunning...
Thread-0 got monitorEnter...
Thread-0 business over...
Thread-0 monitorExit...
Thread-1 got monitorEnter...
Thread-1 business over...
Thread-1 monitorExit...

我们在来看看park、unpark相关的使用

public void test5() throws Exception {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    System.out
        .println(LocalDateTime.now().format(formatter) + " " + Thread.currentThread().getName() + " is running...");
    // 这里让当前线程阻塞6s,注意:如果park第一个参数是true的话,表示绝对时间,这个时间是毫秒级的,也就是系统时间,系统到这个绝对时间后才唤醒执行
    unsafe.park(true, System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(6));
    System.out
        .println(LocalDateTime.now().format(formatter) + " " + Thread.currentThread().getName() + " continue...");
    // 这里让当前线程阻塞3s,注意:如果park第一个参数是false的话,这个是纳秒级别的时间,表示相对当前时间3s后继续唤醒执行
    unsafe.park(false, TimeUnit.SECONDS.toNanos(3));
    System.out
        .println(LocalDateTime.now().format(formatter) + " " + Thread.currentThread().getName() + " continue...");
    // 如果park的第一个参数是false,第二个值是0,则会一直等待,直
首页 上一页 3 4 5 6 7 下一页 尾页 6/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇10、Spring之AOP概述 下一篇new ArrayList 不当导致 CPU 飙升..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目