电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

OpenJDK源碼解析之System.out.println詳解

瀏覽:151日期:2024-07-21 09:34:04
一、前戲

可能不少小伙伴習慣在代碼中使用sout打印一些信息,就像這樣:

System.out.println('hello world!')

做為一位資深干碼人,本著弘揚黨求真務實的精神,必須得來看看這個sout有何玄機~~

首先看調用就知道,out是System類的一個公共靜態成員變量,進入System.java中:

public final static PrintStream out = null;

嗯,不止是public,還是final的。不管,來找找out是在哪里賦值的。。。。。。日嘛找半天沒找到?那就試試直接在類中搜索: out = ,結果如下:

OpenJDK源碼解析之System.out.println詳解

完犢子,整個System類一共將近1300行的代碼,只找到一個和out賦值相關的,還是啥子局部變量fdOut,看起來和out屬性沒有什么關聯啊~ 往上滑滑看看這個是什么方法:

private static void initializeSystemClass() {......FileInputStream fdIn = new FileInputStream(FileDescriptor.in);FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);setIn0(new BufferedInputStream(fdIn));setOut0(newPrintStream(fdOut, props.getProperty('sun.stdout.encoding')));setErr0(newPrintStream(fdErr, props.getProperty('sun.stderr.encoding')));......}

原來如此,看到initializeSystemClass方法,似乎一切都明了了~~

二、JVM源碼分析

initializeSystemClass不是給我們調用的,這個方法會在vm線程初始化后被虛擬機調用。其定義在thread.cpp中:

static void call_initializeSystemClass(TRAPS) { Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK); instanceKlassHandle klass (THREAD, k); JavaValue result(T_VOID); JavaCalls::call_static(&result, klass, vmSymbols::initializeSystemClass_name(), vmSymbols::void_method_signature(), CHECK);}

首先獲取Klass(類元信息在虛擬機中的結構表示,就是一個c++中的類),在vmSymbols.hpp中找找java_lang_System對應的值:

template(java_lang_System, 'java/lang/System')

可以看到代表的就是java.lang.System類,同時,initializeSystemClass_name也定義在vmSymbols.hpp中:

template(initializeSystemClass_name,'initializeSystemClass')

這里使用JavaCalls::call_static就是調用java.lang.System的靜態方法initializeSystemClass。還要再??亂瘓洌?all_initializeSystemClass是在何處調用的?我們回到thread.cpp中,進入Threads::create_vm方法,在其中找到了call_initializeSystemClass方法的調用:

jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {...... call_initializeSystemClass(CHECK_0);......}

然后看看Threads::create_vm是在何處調用的,我們進入jni.cpp,找到JNI_CreateJavaVM方法:

_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {......result = Threads::create_vm((JavaVMInitArgs*) args, &can_try_again);if (result == JNI_OK) {......} else {......}......}

現在已經知道了,JVM啟動后會在初始化JVM的時候調用CreateJavaVM,進而調用initializeSystemClass方法。但是out屬性是如何設置的呢?我們回到java.lang.System#initializeSystemClass方法:

private static void initializeSystemClass() {......FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);setOut0(newPrintStream(fdOut, props.getProperty('sun.stdout.encoding')));......}private static PrintStream newPrintStream(FileOutputStream fos, String enc) { if (enc != null) { try {return new PrintStream(new BufferedOutputStream(fos, 128), true, enc); } catch (UnsupportedEncodingException uee) {}}return new PrintStream(new BufferedOutputStream(fos, 128), true); }

這個方法中唯一和out相關的就是這個setOut0方法調用了,我們來看看這個方法:

private static native void setOut0(PrintStream out);

嗯,這個是一個native方法,沒辦法,又只有回到JVM源碼了。怎么找呢?首選組裝一下本地方法名,根據規則setOut0對應的本地方法應該叫:Java_java_lang_System_setOut0,我們到源碼中找找,然后在System.c中找到了該方法

JNIEXPORT void JNICALLJava_java_lang_System_setOut0(JNIEnv *env, jclass cla, jobject stream){ jfieldID fid =(*env)->GetStaticFieldID(env,cla,'out','Ljava/io/PrintStream;'); if (fid == 0)return; (*env)->SetStaticObjectField(env,cla,fid,stream);}

首先獲取了java.io.PrintStread類型的out靜態成員,嗯,這個就是我們java.lang.System類的靜態成員out:

public final static PrintStream out;

然后將stream參數賦值給它,這個stream就是initializeSystemClass方法中通過newPrintStream方法創建的PrintStream 對象。到現在我們已經明白了,out原來是這樣賦值的,真麻煩~

趁熱打鐵,弄明白了out,接下來看看println。既然out是PrintStream對象,那么到PrintStream中看看println方法:

public void println(String x) {synchronized (this) { print(x); newLine();} }

Java代碼看起來是要親切多了,但是這個synchronized是個什么鬼???

三、坑?

前面我們發現println方法竟然有個synchronized關鍵字,經常在項目中使用sout的小伙伴會不會感覺腦袋嗡嗡的?為什么要嗡嗡?不要忘記我們前面通過JVM源碼跟蹤的System.out的賦值過程,這個out可是單例!你個加了synchronized(this)的虛方法,還是單例的,如果在系統中進行并發使用,后果不用我多說吧?

那可能有人就要說了,那我不用println(“hello world!”)了嘛,我換成print總行了吧?

System.out.print('hello world!');System.out.print('n');

因為print方法好像沒有加鎖啊:

public void print(String s) {if (s == null) { s = 'null';}write(s); }

那我們看看write方法,不好意思:

private void write(String s) {try { synchronized (this) {ensureOpen();textOut.write(s);textOut.flushBuffer();charOut.flushBuffer();if (autoFlush && (s.indexOf(’n’) >= 0)) out.flush(); }}...... }四、總結

不知道有沒有小伙伴經常在項目中使用System.out.println來輸出'日志'?千萬不要亂用喲,不然說不定哪天就被out了~~~

到此這篇關于OpenJDK源碼解析之System.out.println詳解的文章就介紹到這了,更多相關OpenJDK源碼解析內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: OpenJDK
主站蜘蛛池模板: 焊接烟尘净化器__焊烟除尘设备_打磨工作台_喷漆废气治理设备 -催化燃烧设备 _天津路博蓝天环保科技有限公司 | 深圳富泰鑫五金_五金冲压件加工_五金配件加工_精密零件加工厂 | 防水套管厂家_刚性防水套管_柔性防水套管_不锈钢防水套管-郑州中泰管道 | 陶瓷砂磨机,盘式砂磨机,棒销式砂磨机-无锡市少宏粉体科技有限公司 | 代理记账_免费注册公司_营业执照代办_资质代办-【乐财汇】 | 昆明网络公司|云南网络公司|昆明网站建设公司|昆明网页设计|云南网站制作|新媒体运营公司|APP开发|小程序研发|尽在昆明奥远科技有限公司 | nalgene洗瓶,nalgene量筒,nalgene窄口瓶,nalgene放水口大瓶,浙江省nalgene代理-杭州雷琪实验器材有限公司 | 物和码官网,物和码,免费一物一码数字化营销SaaS平台 | 噪声治理公司-噪音治理专业隔音降噪公司 | 环压强度试验机-拉链拉力试验机-上海倾技仪器仪表科技有限公司 | Eiafans.com_环评爱好者 环评网|环评论坛|环评报告公示网|竣工环保验收公示网|环保验收报告公示网|环保自主验收公示|环评公示网|环保公示网|注册环评工程师|环境影响评价|环评师|规划环评|环评报告|环评考试网|环评论坛 - Powered by Discuz! | 数年网路-免费在线工具您的在线工具箱-shuyear.com | 不锈钢列管式冷凝器,换热器厂家-无锡飞尔诺环境工程有限公司 | 减速机电机一体机_带电机减速器一套_德国BOSERL电动机与减速箱生产厂家 | 北京环球北美考试院【官方网站】|北京托福培训班|北京托福培训 | 建筑工程资质合作-工程资质加盟分公司-建筑资质加盟 | 网站优化公司_SEO优化_北京关键词百度快速排名-智恒博网络 | 快速门厂家批发_PVC快速卷帘门_高速门_高速卷帘门-广州万盛门业 快干水泥|桥梁伸缩缝止水胶|伸缩缝装置生产厂家-广东广航交通科技有限公司 | 不锈钢列管式冷凝器,换热器厂家-无锡飞尔诺环境工程有限公司 | 青岛代理记账_青岛李沧代理记账公司_青岛崂山代理记账一个月多少钱_青岛德辉财税事务所官网 | 一体化预制泵站-一体化提升泵站-一体化泵站厂家-山东康威环保 | 武汉天安盾电子设备有限公司 - 安盾安检,武汉安检门,武汉安检机,武汉金属探测器,武汉测温安检门,武汉X光行李安检机,武汉防爆罐,武汉车底安全检查,武汉液体探测仪,武汉安检防爆设备 | 干洗店加盟_洗衣店加盟_干洗店设备-伊蔻干洗「武汉总部」 | 南京兰江泵业有限公司-水解酸化池潜水搅拌机-絮凝反应池搅拌机-好氧区潜水推进器 | 众能联合-提供高空车_升降机_吊车_挖机等一站工程设备租赁 | 游泳池设计|设备|配件|药品|吸污机-东莞市太平洋康体设施有限公司 | 高压油管,液压接头,液压附件-烟台市正诚液压附件 | 土壤有机碳消解器-石油|表层油类分析采水器-青岛溯源环保设备有限公司 | 立式硫化罐-劳保用品硫化罐-厂家直销-山东鑫泰鑫硫化罐厂家 | 塑料造粒机「厂家直销」-莱州鑫瑞迪机械有限公司 | 环保袋,无纺布袋,无纺布打孔袋,保温袋,环保袋定制,环保袋厂家,环雅包装-十七年环保袋定制厂家 | AR开发公司_AR增强现实_AR工业_AR巡检|上海集英科技 | 皮带式输送机械|链板式输送机|不锈钢输送机|网带输送机械设备——青岛鸿儒机械有限公司 | 一路商机网-品牌招商加盟优选平台-加盟店排行榜平台 | 气动调节阀,电动调节阀,自力式压力调节阀,切断阀「厂家」-浙江利沃夫自控阀门 | 污水/卧式/潜水/钻井/矿用/大型/小型/泥浆泵,价格,参数,型号,厂家 - 安平县鼎千泵业制造厂 | 行吊_电动单梁起重机_双梁起重机_合肥起重机_厂家_合肥市神雕起重机械有限公司 | 高速混合机_锂电混合机_VC高效混合机-无锡鑫海干燥粉体设备有限公司 | 全自动五线打端沾锡机,全自动裁线剥皮双头沾锡机,全自动尼龙扎带机-东莞市海文能机械设备有限公司 | CCE素质教育博览会 | CCE素博会 | 教育展 | 美育展 | 科教展 | 素质教育展 | 飞行者联盟-飞机模拟机_无人机_低空经济_航空技术交流平台 |