成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

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

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

瀏覽:226日期: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
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
欧美日韩国产精品成人| 久久久91精品国产一区二区精品| 欧美日韩1234| 日本一不卡视频| 欧美亚洲一区| 一级女性全黄久久生活片免费| 欧美日韩国产不卡在线看| 日韩一级视频免费观看在线| 国产在线不卡一卡二卡三卡四卡| 色94色欧美sute亚洲线路二| 亚洲一区二区精品久久av| 中文精品视频| 一区二区三区精品视频| 亚洲视频免费| 国产精品动漫网站| 欧美日韩在线观看一区二区三区| 欧美精品一区二区三区很污很色的| 激情欧美日韩一区二区| 欧美吻胸吃奶大尺度电影| 久久精品国内一区二区三区| 欧美亚洲一区二区三区四区| 久久99精品国产| 欧美亚洲国产bt| 日韩av成人高清| 色婷婷av一区二区三区之一色屋| 午夜精品久久久久久久久久久| 欧美亚洲一区二区三区| 视频在线在亚洲| 91成人在线精品| 久久精品国产久精国产| 91精品欧美福利在线观看| 国产主播一区二区| 欧美丰满美乳xxx高潮www| 国产中文字幕精品| 日韩色视频在线观看| 国产成人精品免费一区二区| 日韩午夜精品电影| 成人一区二区三区视频在线观看| 精品日韩欧美一区二区| 欧美1区免费| 亚洲免费观看高清在线观看| 99国产一区| 日韩专区欧美专区| 欧美日韩日日摸| 国产在线精品国自产拍免费| 欧美大胆人体bbbb| 91美女片黄在线观看| 中文字幕一区二区三区在线观看| 亚洲免费观看| 亚洲超碰97人人做人人爱| 在线观看视频一区| 国产sm精品调教视频网站| 精品伦理精品一区| 一区二区亚洲| 图片区日韩欧美亚洲| 在线一区二区三区做爰视频网站| 狠狠色丁香久久婷婷综合_中 | 欧美丝袜丝nylons| 成人中文字幕在线| 中文子幕无线码一区tr| 日韩午夜免费视频| 免费精品99久久国产综合精品| 欧美一级理论片| 欧美激情日韩| 一区二区久久久久久| 欧美日韩精品一区二区三区四区| 成人精品国产免费网站| 中文字幕一区三区| 91国内精品野花午夜精品| 国产成人av福利| 中文字幕一区在线观看视频| 色老头久久综合| 不卡视频在线看| 亚洲精品欧美专区| 欧美日韩在线观看一区二区| 91麻豆精品视频| 亚洲第四色夜色| 欧美日韩在线电影| 菠萝蜜视频在线观看一区| 中文字幕一区二区三| 在线欧美一区二区| 99re在线精品| 亚洲大型综合色站| 日韩视频一区二区| 国产欧美日韩综合一区在线播放 | 日韩高清电影一区| 欧美tickling挠脚心丨vk| 亚洲精美视频| 久久国产福利国产秒拍| 欧美极品少妇xxxxⅹ高跟鞋| 久久一区二区三区四区五区| 91天堂素人约啪| 奇米精品一区二区三区四区 | 91久久精品一区二区二区| 97精品视频在线观看自产线路二| 亚洲午夜激情网站| 日韩午夜激情视频| 欧美一级久久| 99久久综合精品| 天堂资源在线中文精品| 久久伊人中文字幕| 一本久久精品一区二区| 欧美国产先锋| 久99久精品视频免费观看| 中文字幕中文字幕在线一区| 欧美日韩专区在线| 亚洲激情国产| 成人性生交大片| 五月激情丁香一区二区三区| 欧美激情一区二区| 欧美日韩成人综合在线一区二区| 亚洲东热激情| 成人性生交大片免费看中文网站| 亚洲成人黄色影院| 国产日韩影视精品| 在线观看成人小视频| 伊人久久综合| 粉嫩av一区二区三区| 日韩福利电影在线观看| 中文字幕在线观看不卡| 欧美一区二区三区视频在线 | 老鸭窝毛片一区二区三区| 色综合天天狠狠| 国产精品一区二区在线观看网站| 一区二区三区国产精华| 26uuu久久天堂性欧美| 欧美艳星brazzers| 国产午夜久久| 欧美黄色精品| 国产福利一区在线| 日本伊人色综合网| 亚洲精品视频在线看| 久久久久久久网| 欧美日韩mp4| 久久久久中文| 亚洲国产电影| 91蜜桃视频在线| 国产成人啪午夜精品网站男同| 麻豆国产一区二区| 亚洲第一电影网| 成人欧美一区二区三区1314| 精品国产精品一区二区夜夜嗨| 91久久香蕉国产日韩欧美9色| 日韩视频中文| 亚洲视频一二| 欧美在线免费一级片| 成人黄色软件下载| 国产美女娇喘av呻吟久久| 五月激情综合色| 亚洲一区影音先锋| 中文字幕日韩av资源站| 久久先锋影音av鲁色资源| 日韩一级黄色片| 欧美三级电影网| 在线亚洲高清视频| 国产久一道中文一区| 亚洲精品中文字幕在线| 欧美连裤袜在线视频| eeuss鲁一区二区三区| 国产高清亚洲一区| 国产一区二区电影| 久99久精品视频免费观看| 麻豆一区二区三区| 欧美aⅴ一区二区三区视频| 天天综合网 天天综合色| 亚洲国产视频网站| 亚洲精品一卡二卡| 亚洲你懂的在线视频| 自拍偷在线精品自拍偷无码专区| 日本一区二区成人| 国产午夜精品久久久久久免费视| 日韩欧美国产系列| 日韩视频免费观看高清完整版| 欧美电影一区二区三区| 欧美男男青年gay1069videost | 国产精品久久久久9999高清| 亚洲经典自拍| 国产日韩欧美一区二区| 欧美日韩国产高清视频| 欧美在线观看天堂一区二区三区| 欧美永久精品| 欧美日韩国产三区| 亚洲激情亚洲| 亚洲国产精品第一区二区三区| 在线精品亚洲| 国产日韩欧美三级| 亚洲一区二区三区免费观看| 国产精品日本欧美一区二区三区| 一区二区高清视频| 亚洲免费中文| 久久综合一区二区三区| 欧美性受xxxx| 宅男噜噜噜66一区二区66| 欧美一级精品在线| 亚洲精品一区在线观看| 国产清纯在线一区二区www| 自拍偷自拍亚洲精品播放| 亚洲国产一区二区视频| 肉肉av福利一精品导航| 亚洲国产精品久久不卡毛片|