专栏首页实战dockerJava的wait和notify学习三部曲之二:修改JVM源码看参数

Java的wait和notify学习三部曲之二:修改JVM源码看参数

在上一章《

编译JVM源码需要搭建编译环境,推荐使用docker,因为我已准备好了一个完善的编译环境镜像,详情请参照《

如果您用的是linxu或Mac操作系统,那么可直接安装官方docker软件;如果您用的是win10专业版,也能直接安装官方docker软件;如果是win10家庭版是无法安装docker的,这时可以装vmware,再安装linux系统,推荐centos7,再在centos7上安装docker,参考《》;

在docker上启动了bolingcavalry/bolingcavalryopenjdk:0.0.1镜像后:a. 执行docker exec -it compilejdk/bin/bash进入容器;b. 执行vi /usr/local/openjdk/hotspot/src/share/vm/runtime/objectMonitor.cpp打开要修改的文件;c. 找到方法void ObjectMonitor::notify(TRAPS),找到方法内代码:“int Policy = Knob_MoveNotifyee ;”,在下面新增一行“printf("*** Policy : %d\n", Policy);”,如下图:

d. 找到方法void ATTR ObjectMonitor::exit(bool notsuspended, TRAPS),找到方法内代码"int QMode = KnobQMode ;",在下面新增一行“printf("*** QMode : %d\n", QMode);”,如下图:

e. 在/usl/local/openjdk/目录下执行./configure --with-debug-level=slowdebug完成配置检查;f. 在/usl/local/openjdk/目录下执行bluemake all ZIPDEBUGINFOFILES=0 DISABLEHOTSPOTOSVERSIONCHECK=OK CONF=linux-x86_64-normal-server-slowdebug开始编译,大约20分钟,编译完成,如下图:

g. 编译完成后进入目录,创建文件NotifyDemo.java文件,内容如下:

public class NotifyDemo {	
    private static void sleep(long sleepVal){	
        try{	
            Thread.sleep(sleepVal);	
        }catch(Exception e){	
            e.printStackTrace();	
        }	
    }	
    private static void log(String desc){	
        System.out.println(Thread.currentThread().getName() + " : " + desc);	
    }	
    Object lock = new Object();	
    public void startThreadA(){	
        new Thread(() -> {	
            synchronized (lock){	
                log("get lock");	
                startThreadB();	
                log("start wait");	
                try {	
                    lock.wait();	
                }catch(InterruptedException e){	
                    e.printStackTrace();	
                }	
                log("get lock after wait");	
                log("release lock");	
            }	
        }, "thread-A").start();	
    }	
    public void startThreadB(){	
        new Thread(()->{	
            synchronized (lock){	
                log("get lock");	
                startThreadC();	
                sleep(100);	
                log("start notify");	
                lock.notify();	
                log("release lock");	
            }	
        },"thread-B").start();	
    }	
    public void startThreadC(){	
        new Thread(() -> {	
            synchronized (lock){	
                log("get lock");	
                log("release lock");	
            }	
        }, "thread-C").start();	
    }	
    public static void main(String[] args){	
        new NotifyDemo().startThreadA();	
    }	
}

h. 在此目录下执行./javac NotifyDemo.java编译源码;i. 在此目录下执行./java NotifyDemo执行class,可以看到输出如下图:

如上图所示,已将运行时的Policy和QMode打印出来,我们来分析一下吧:

首先,Policy=2,表示线程A从等待队列WaitSet中被取出,又因为EntryList为空,所以A放入了EntryList首位,BlOCKING状态的线程C在cxq,所以A和C放在不同的队列中:

其次,QMode=0,在ObjectMonitor::exit方法中,对QMode等于1、2、3、4的时候都有特殊处理(例如从EntryList中取出数据),但是对QMode等于0没有特殊处理,而是依次从EntryList中取出线程来唤醒,如下图,由于A放在_EntryList中,所以A总是先唤醒;

通过日志确定参数值,在结合代码分析,我们把上一章的遗留问题已经搞清楚了,在下一章中,我们会继续修改源码,操控线程A和C对锁的抢占顺序。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java的wait()、notify()学习三部曲之二:修改JVM源码看参数

    在上一章《 Java的wait()、notify()学习三部曲之一:JVM源码分析》中,我们通过JVM源码分析了线程同步的相关操作,但还是留下了一些疑惑未解:在...

    程序员欣宸
  • golang实战之flag包

    版权声明:欢迎转载,请注明出处,谢谢。 https://blog.csdn.net/boli...

    程序员欣宸
  • 没有了可用Task slot,Flink新增任务会怎样?

    看来要想任务顺利执行,首先要保证slot数量够用,目前机器内存是够用的,那么就把slot数量调大些吧;

    程序员欣宸
  • Java的wait()、notify()学习三部曲之二:修改JVM源码看参数

    在上一章《 Java的wait()、notify()学习三部曲之一:JVM源码分析》中,我们通过JVM源码分析了线程同步的相关操作,但还是留下了一些疑惑未解:在...

    程序员欣宸
  • 同时具备多线程和多进程安全的写日志工具

    接口请浏览:https://github.com/eyjian/mooon/blob/master/mooon/include/mooon/sys/log.h ...

    一见
  • WebGL2系列之图元重启

    在使用WebGL绘制图形的时候,大多数情况下,绘制一个图形的时候,其各个图元都是相连的。 但是在一些情况下,我们需要绘制图元不相连的图形,如果绘制的模式是gl....

    用户3158888
  • HDOJ 1014

    Uniform Generator Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536...

    用户1154259
  • 流水灯

    module led_test ( clk, // 开发板上输入时钟: 50Mhz ...

    瓜大三哥
  • MapX中实现友好的交互

            MapX的标注,修改标注功能尽管都有,但都十分的难用,操作起来,用户体验非常糟糕。不光编程难以控制,操作起来也不方便:工具选择要不断的切换,移动...

    用户1075292
  • opencv报错

    错误一:error: (-215) !empty() in function cv::CascadeClassifier::detectMultiScale

    用户7625592

扫码关注云+社区

领取腾讯云代金券