欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

筆者帶你剖析Java7.x新特性

系統(tǒng) 1848 0

前言

最近在ITeye上看見(jiàn)一些朋友正在 激烈 討論關(guān)于Java7.x的一些 語(yǔ)法結(jié)構(gòu) ,所以筆者有些手癢,特此 探尋 了7.x(此篇博文筆者使用的是目前最新版本的JDK-7u15)的一些 新特性 分享給大家。雖然目前很多開(kāi)發(fā)人員至今還在沿用Java4.x(筆者項(xiàng)目至今沿用4.x),但這并不是成為不前進(jìn)的 借口 。想了解Java的發(fā)展,想探尋Java的未來(lái),那么你務(wù)必需要時(shí)刻保持一顆永不落后的

?

當(dāng)然筆者此篇博文 不代表官方觀點(diǎn) ,如果有朋友覺(jué)得筆者的話語(yǔ)是妙論,希望指正提出,筆者會(huì)在第一時(shí)間糾正博文內(nèi)容。在此筆者先謝過(guò)各位利用寶貴的時(shí)間閱讀此篇博文,最后筆者祝愿各位新年大吉,工作順利。再次啰嗦一點(diǎn), SSJ的系列博文,筆者將會(huì)在本周更新 ,希望大家體諒。

?

目錄

一、自動(dòng)資源管理;

二、“<>”類型推斷運(yùn)算符;

三、字面值下劃線支持;

四、switch字面值支持;

五、聲明二進(jìn)制字面值;

六、catch表達(dá)式調(diào)整;

七、文件系統(tǒng)改變;

八、探討Java I/O模型;

九、Swing Framework(JSR 296規(guī)范)支持;

十、JVM內(nèi)核升級(jí)之Class Loader架構(gòu)調(diào)整;

十一、JVM內(nèi)核升級(jí)之Garbage Collector調(diào)整(時(shí)間倉(cāng)促,后期講解);

?

一、自動(dòng)資源管理

早在7.x版本之前,某些可回收資源比如:I/O鏈接、DB連接、TCP/UDP連接。開(kāi)發(fā)人員都需要在使用后對(duì)其進(jìn)行 手動(dòng) 關(guān)閉,如果不關(guān)閉或者忘記關(guān)閉這些資源,就會(huì)長(zhǎng)期 霸占 JVM內(nèi)部的資源,極大程度上 影響 了JVM的資源分配。就像內(nèi)存管理一樣,開(kāi)發(fā)人員夢(mèng)寐以求的就是希望有一天再也無(wú)需關(guān)注 繁瑣 的資源管理(資源創(chuàng)建、資源就緒、資源回收)。值得慶幸的是7.x為我們帶來(lái)了一次徹頭徹尾改變,我們將再也不必以手動(dòng)管理我們的資源。

早在Java5.x的時(shí)候,Java API為開(kāi)發(fā)人員提供了一個(gè)Closeable接口。該接口中包含一個(gè)close()方法,允許所有可回收資源的類型對(duì)其進(jìn)行重寫(xiě)實(shí)現(xiàn)。7.x版本中幾乎所有的資源類型都實(shí)現(xiàn)了Closeable接口,并重寫(xiě)了close()方法。也就是說(shuō)所有可回收的系統(tǒng)資源,我們將 不必 每次使用完后調(diào)用close()方法進(jìn)行資源回收,這一切全部交接給自動(dòng)資源管理器去做即可。

例如Reader資源類型繼承Closeable接口實(shí)現(xiàn)資源自動(dòng)管理:

      public abstract class Reader implements Readable, Closeable
    

??

當(dāng)然如果你需要在程序中使用自動(dòng)資源管理,還需要使用API提供的新語(yǔ)法支持,這類語(yǔ)法包含在try語(yǔ)句塊內(nèi)部。看到這里你可能不禁感嘆,try也能 支持表達(dá)式 了,是的7.x確實(shí)允許try使用表達(dá)式的 語(yǔ)法方式 實(shí)現(xiàn)自動(dòng)資源管理,但 僅限 于資源類型。

使用try表達(dá)式實(shí)現(xiàn)自動(dòng)資源管理:

      try(BufferedReader reader = new BufferedReader(new FileReader("路徑"));)
{
	//...
}
catch(Exception e)
{
	e.printStackTrace();
}
    

??

? 二、“<>”類型推斷運(yùn)算符

Java 5.x 新增了許多新的功能,在這些新引入的功能中,泛型最為 重要 。泛型是一種新的語(yǔ)法元素,泛型的出現(xiàn)導(dǎo)致整個(gè) Java API 都發(fā)生了變化( 比如: Java 集合框架就使用了泛型語(yǔ)法)。

在泛型沒(méi)有出現(xiàn)之前,我們都是將 Object 類作為通用的 任意數(shù)據(jù)類型 使用。因?yàn)樵? Java 語(yǔ)言中, Object 類是所有類的超類 。但是使用 Object 類作為任意數(shù)據(jù)類型并不是安全的,因?yàn)樵诤芏鄷r(shí)候我們需要將 Object 類型向下轉(zhuǎn)換,在這些轉(zhuǎn)換過(guò)程中偶爾也可能出現(xiàn) 不匹配 的類型轉(zhuǎn)換錯(cuò)誤。泛型的出現(xiàn)則很好的解決了 Object 類型所存在的 安全性 問(wèn)題,且泛型還擴(kuò)展了代碼的重用性。

泛型的核心概念就是 參數(shù)化類型 ,所謂參數(shù)化類型指的就是開(kāi)發(fā)人員可以在 外部 指定的數(shù)據(jù)類型來(lái)創(chuàng)建泛型類 泛型接口和泛型方法。

使用泛型類型示例:

      List<String> list = new ArrayList<String>();
    

??

通過(guò)上述程序示例我們可以看出,筆者定義了一個(gè)泛型類型為String的List集合。這樣一來(lái)List集合的泛型參數(shù)將會(huì)被定義為String類型。但是你有沒(méi)有想過(guò),使用里氏替換原則或者實(shí)例化泛型類型時(shí),其實(shí)現(xiàn)可以簡(jiǎn)化泛型類型聲明嗎?答案是肯定的,在Java7.x中,允許使用運(yùn)算符“<>”來(lái)做類型推斷。也就是說(shuō)你只需要在聲明時(shí)標(biāo)注泛型類型,實(shí)現(xiàn)時(shí) 無(wú)需重復(fù) 標(biāo)注。

使用“<>”類型推斷運(yùn)算符簡(jiǎn)化泛型語(yǔ)法:

      List<String> list = new ArrayList<>();
    

??

三、字面值下劃線支持

不知道大家有沒(méi)有過(guò)同筆者一樣的煩惱,早在Java7.x版本之前,咱們?cè)诙xint或者long類型等變量的字面值時(shí),往往會(huì)因?yàn)槠涠x的 值過(guò)長(zhǎng) ,從而嚴(yán)重影響后續(xù)的 可讀性 。如果你也是這么覺(jué)得,那么你可以考慮使用Java7.x為字面值操作提供的可讀性優(yōu)化。那便是允許你直接的字面值中使用符號(hào)“_”進(jìn)行 切分 ,這樣一來(lái)不僅可以提升可讀性,還能夠清晰的分辨出字面值的長(zhǎng)度。當(dāng)然程序運(yùn)行時(shí)自然會(huì)將“_”符號(hào)進(jìn)行提取再做運(yùn)算。

使用“_”符號(hào)進(jìn)行字面值可讀性優(yōu)化:

      int money = 100_000_000;
    

??

四、switch字面值支持

Java一共為開(kāi)發(fā)人員提供了2種多路分支語(yǔ)句,一種是大家常用的if-else,另一種則是switch語(yǔ)句。早在Java7.x版本之前, switch 語(yǔ)句表達(dá)式值只能定義 byte short int char等 4 類型,且該語(yǔ)句表達(dá)式值 只能 匹配一個(gè) ,故不能重復(fù)。但是Java7.x的到來(lái)允許switch定義另一種 全新 的表達(dá)式值,那就是String類型。

使用String類型作為Switch表達(dá)式值:

      switch("a")
{
	case "a":
		System.out.println("a");
		break;
	case "b":
		System.out.println("b");
}
    

?

五、聲明二進(jìn)制字面值

? Java C 語(yǔ)言、 C++ 語(yǔ)言直接相關(guān)。 Java 語(yǔ)言繼承了 C 語(yǔ)言的語(yǔ)法結(jié)構(gòu),而 OMT(Object Modeling Technique ,對(duì)象模型)則是直接從 C++ 語(yǔ)言改編而來(lái)的。所以早在 Java7.x 版本之前,開(kāi)發(fā)人員只能夠定義十進(jìn)制、八進(jìn)制、十六進(jìn)制等字面值。但是現(xiàn)在你完全可以使用“ 0b ”字符為 前綴 定義二進(jìn)制字面值。
定義二進(jìn)制字面值:

      int test = 0b010101; 
    

?

當(dāng)然這里筆者需要提示你的是,雖然咱們可以直接在程序中定義二進(jìn)制字面值。但是在程序運(yùn)算時(shí),仍然會(huì)將其 轉(zhuǎn)換 成十進(jìn)制展開(kāi)運(yùn)算和輸出。

?

六、catch表達(dá)式調(diào)整

談到catch語(yǔ)句的時(shí)候,不得不提到try語(yǔ)句,因?yàn)樗鼈儽舜酥g存在 相互依賴、相互關(guān)聯(lián) 的關(guān)系。在Java程序中捕獲一個(gè)異常采用的是try和catch語(yǔ)句,try語(yǔ)句里面所包含的代碼塊都是需要進(jìn)行 異常監(jiān)測(cè) 的,而catch語(yǔ)句里面所包含的代碼塊,則是告訴程序當(dāng)異常發(fā)生的時(shí)候所需要執(zhí)行的 異常處理

談到捕獲異常,在Java7.x之前有2種方式。第一種是采用定義多個(gè)catch代碼塊,另外一種則是直接使用Exception(可恢復(fù)性異常超類)進(jìn)行捕獲。但是現(xiàn)在,如果你覺(jué)得不想 籠統(tǒng) 的將所有異常定義為Exception進(jìn)行捕獲,或者 糾結(jié) 于反復(fù)定義catch代碼塊,那么你完全可以采用Java7.x的catch表達(dá)式調(diào)整。Java7.x允許你在catch表達(dá)式內(nèi)部使用“|”運(yùn)算符匹配多個(gè)異常類型,當(dāng)觸發(fā)異常時(shí),異常類型將自動(dòng)進(jìn)行 類型匹配 操作。

使用“|”運(yùn)算符定義catch表達(dá)式:

      try 
{
	//...
}
catch (SQLException | Exception e) 
{
	e.printStackTrace();
}
    

?

七、文件系統(tǒng)改變

既然本章節(jié)咱們已經(jīng)談到了Java的文件系統(tǒng)(FileSystem),那么必然 同樣 也會(huì)關(guān)聯(lián)到I/O技術(shù)。其實(shí) 所謂 I/O(Input/Outp ut) 指的就是數(shù)據(jù)輸入 / 輸出的 過(guò)程 ,我們稱之為流( 數(shù)據(jù)通信通道 )這個(gè)概念。 比如當(dāng) Java 應(yīng)用程序需要讀取目標(biāo)數(shù)據(jù)源的數(shù)據(jù)時(shí),則開(kāi)啟輸入流。需要寫(xiě)入時(shí),則開(kāi)啟輸出流。數(shù)據(jù)源允許是本地磁盤(pán)、內(nèi)存或者是網(wǎng)絡(luò)中的數(shù)據(jù)。

向目標(biāo)數(shù)據(jù)源讀取數(shù)據(jù):

筆者帶你剖析Java7.x新特性

?

向目標(biāo)數(shù)據(jù)源寫(xiě)入數(shù)據(jù):

筆者帶你剖析Java7.x新特性

Java的文件系統(tǒng)主要由java.io及java.nio兩個(gè)包內(nèi)的組件 構(gòu)成 早在Java7.x之前,文件的操作一向都比較 棘手 。當(dāng)然筆者這里提出的棘手,更多的是指向Java API對(duì)文件的管理的 不便 。比如咱們需要編寫(xiě)一個(gè)程序,這個(gè)程序的功能僅僅只是拷貝文件后進(jìn)行粘貼。但就是連這樣簡(jiǎn)單的程序邏輯實(shí)現(xiàn),開(kāi)發(fā)人員動(dòng)則都需要編寫(xiě)幾十行 有效代碼

使用Java File API操作文件核心示例:

      /* 復(fù)制目標(biāo)數(shù)據(jù)源數(shù)據(jù) */
BufferedInputStream reader = new BufferedInputStream(
		new FileInputStream(COPYFILEPATH));
byte[] content = new byte[reader.available()];
reader.read(content);

/* 將復(fù)制數(shù)據(jù)粘貼至新目錄 */
BufferedOutputStream write = new BufferedOutputStream(
		new FileOutputStream(PASTEFILEPATH));
write.write(content);
    

?

通過(guò)上述程序示例我們可以看出,僅僅只是編寫(xiě)一個(gè)簡(jiǎn)單的文件復(fù)制粘貼邏輯,我們的代碼量都大得 驚人 。如果你也認(rèn)同上述程序的 繁瑣 ,那么你完全有必要體驗(yàn)下Java7.x對(duì)文件系統(tǒng)的一次全新 改變

Java7.x推出了全新的NIO.2 API以此改變針對(duì)文件管理的不便,使得在java.nio.file包下使用 Path、Paths、 Files、 WatchService、 FileSystem 等常用類型可以很好的 簡(jiǎn)化 開(kāi)發(fā)人員對(duì)文件管理的編碼工作。

咱們就先從Path接口開(kāi)始進(jìn)行講解吧。Path接口的 某些功能 其實(shí)可以和java.io包下的File類型 等價(jià) ,當(dāng)然這些功能僅限于 只讀操作 。在實(shí)際開(kāi)發(fā)過(guò)程中,開(kāi)發(fā)人員可以聯(lián)用Path接口和Paths類型,從而獲取文件的一系列上下文信息。

Path接口常用方法如下:

方法名稱 方法返回類型 方法描述
getNameCount() int 獲取當(dāng)前文件節(jié)點(diǎn)數(shù)
getFileName() java.nio.file.Path 獲取當(dāng)前文件名稱
getRoot() java.nio.file.Path 獲取當(dāng)前文件根目錄
getParent() java.nio.file.Path 獲取當(dāng)前文件上級(jí)關(guān)聯(lián)目錄

?

聯(lián)用Path接口和Paths類型獲取文件信息:

      @Test
public void testFile() {
	Path path = Paths.get("路徑:/文件");
	System.out.println("文件節(jié)點(diǎn)數(shù):" + path.getNameCount());   
	System.out.println("文件名稱:" + path.getFileName());   
	System.out.println("文件根目錄:" + path.getRoot());   
	System.out.println("文件上級(jí)關(guān)聯(lián)目錄:" + path.getParent());   
}
    

?

通過(guò)上述程序示例我們可以看出,聯(lián)用Path接口和Paths類型可以很方便的訪問(wèn)到目標(biāo)文件的上下文信息。當(dāng)然這些操作全都是只讀的,如果開(kāi)發(fā)人員想對(duì)文件進(jìn)行其它 非只讀 操作,比如文件的創(chuàng)建、修改、刪除等操作,則可以使用Files類型進(jìn)行操作。

Files類型常用方法如下:

方法名稱 方法返回類型 方法描述
createFile() java.nio.file.Path 在指定的目標(biāo)目錄創(chuàng)建新文件
delete() void 刪除指定目標(biāo)路徑的文件或文件夾
copy() java.nio.file.Path 將指定目標(biāo)路徑的文件拷貝到另一個(gè)文件中
move() java.nio.file.Path 將指定目標(biāo)路徑的文件轉(zhuǎn)移到其他路徑下,并刪除源文件

?

使用Files類型復(fù)制、粘貼文件示例:

      Files.copy(Paths.get("路徑:/源文件"), Paths.get("路徑:/新文件"));
    

?

通過(guò)上述程序示例我們可以看出,使用Files類型來(lái)管理文件,相對(duì)于傳統(tǒng)的I/O方式來(lái)說(shuō)更加 方便 簡(jiǎn)單 。因?yàn)? 具體的操作實(shí)現(xiàn)將全部移交給NIO.2 API,開(kāi)發(fā)人員則無(wú)需關(guān)注。

Java7.x還為開(kāi)發(fā)人員提供了一套 全新 的文件系統(tǒng)功能,那就是文件監(jiān)測(cè)。在此或許有很多朋友并不知曉文件監(jiān)測(cè)有何意義及目,那么請(qǐng)大家回想下調(diào)試成 熱發(fā)布 功能 后的Web容器。當(dāng)項(xiàng)目迭代后并重新部署時(shí),開(kāi)發(fā)人員無(wú)需對(duì)其進(jìn)行手動(dòng)重啟,因?yàn)閃eb容器一旦監(jiān)測(cè)到文件發(fā)生改變后,便會(huì)自動(dòng)去 適應(yīng) 這些“變化”并重新進(jìn)行內(nèi)部 裝載 。Web容器的熱發(fā)布功能同樣也是基于文件監(jiān)測(cè)功能,所以不得不承認(rèn),文件監(jiān)測(cè)功能的出現(xiàn)對(duì)于Java文件系統(tǒng)來(lái)說(shuō)是具有 重大意義 的。

?

提示

就事論事而言,Java7.x的文件監(jiān)測(cè)功能多少存在一些性能和功能上的 缺陷 。但隨著Java后續(xù)版本的迭代,筆者相信會(huì)有那么一天,足以讓某些整天在論壇上打口水戰(zhàn)的“高手”們閉嘴。

?

如果在程序中需要使用Java7.x的文件監(jiān)測(cè)功能,那么我們務(wù)必需要了解 java.nio.file包下的 WatchService接口。 WatchService接口不僅 作為監(jiān)測(cè)服務(wù),還管理著具體的 監(jiān)控細(xì)節(jié)

我們可以通過(guò)使用 java.nio.file包下的FileSystems類型,并調(diào)用FileSystems類型的newWatchService()方法,從而獲取到 WatchService接口的對(duì)象實(shí)例。

獲取 WatchService接口實(shí)例:

      WatchService watchService = FileSystems.getDefault()
		.newWatchService();
    

?

文件監(jiān)測(cè)是基于 件驅(qū)動(dòng) 的,事件觸發(fā)是作為監(jiān)測(cè)的 先決條件 。開(kāi)發(fā)人員可以使用java.nio.file包下的StandardWatchEventKinds類型提供的3種字面常量來(lái)定義監(jiān)測(cè)事件類型,值得注意的是監(jiān)測(cè)事件需要和 WatchService實(shí)例一起進(jìn)行 注冊(cè)

StandardWatchEventKinds類型提供的監(jiān)測(cè)事件:

1、 ENTRY_CREATE:文件或文件夾新建事件

2、 ENTRY_DELETE:文件或文件夾刪除事件

3、 ENTRY_MODIFY:文件或文件夾粘貼事件

?

使用 WatchService類型實(shí)現(xiàn)文件監(jiān)控完整示例:
      @Test
public void testWatch() {
	/* 監(jiān)控目標(biāo)路徑 */
	Path path = Paths.get("C:/");
	try {
		/* 創(chuàng)建文件監(jiān)控對(duì)象 */
		WatchService watchService = FileSystems.getDefault()
				.newWatchService();

		/* 注冊(cè)文件監(jiān)控的所有事件類型 */
		path.register(watchService, ENTRY_CREATE, ENTRY_DELETE,
				ENTRY_MODIFY);

		/* 循環(huán)監(jiān)測(cè)文件 */
		while (true) {
			WatchKey watchKey = watchService.take();

			/* 迭代觸發(fā)事件的所有文件 */
			for (WatchEvent<?> event : watchKey.pollEvents())
				System.out.println(event.context().toString() + " 事件類型:"
						+ event.kind());
			if (!watchKey.reset())
				return;
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}
    

??

通過(guò)上述程序示例我們可以看出,使用 WatchService接口 進(jìn)行文件監(jiān)控非常簡(jiǎn)單和方便。首先我們需要定義好目標(biāo)監(jiān)控路徑,然后 調(diào)用 FileSystems 類型的newWatchService()方法 創(chuàng)建WatchService對(duì)象。接下來(lái)我們還需使用Path接口的register()方法注冊(cè)WatchService實(shí)例及監(jiān)控事件。當(dāng)這些基礎(chǔ)作業(yè)層全部準(zhǔn)備好后,我們?cè)倬帉?xiě)外圍 實(shí)時(shí)監(jiān)測(cè) 循環(huán)。最后迭代WatchKey來(lái)獲取所有 觸發(fā) 監(jiān)控事件的文件即可。

?

提示

如果在項(xiàng)目中使用上述程序示例,筆者建議你最好將這段監(jiān)控代碼進(jìn)行 異步化 。因?yàn)樗姥h(huán)會(huì)占用主線程,后續(xù)代碼將永遠(yuǎn)得不到執(zhí)行機(jī)會(huì)。

?

八、探討Java I/O模型

在基于分布式的編程環(huán)境中,系統(tǒng)性能的 瓶頸 往往由I/O讀寫(xiě)性決定。這是不可否認(rèn)的事實(shí),也是眾多開(kāi)發(fā)人員首要考慮的優(yōu)化問(wèn)題。如果在Windows環(huán)境下我們使用阻塞I/O模型來(lái)編寫(xiě)分布式應(yīng)用,其維護(hù)成本的往往超出你的想象。因?yàn)榭蛻舳说? 鏈接數(shù)量直接決定了服務(wù)器內(nèi)存開(kāi)辟的線程數(shù)量 * 2 (包含:接受線程、輸出線程),并且這些線程是無(wú)法采取線程池優(yōu)化的,因?yàn)榫€程的執(zhí)行之間 大于 其創(chuàng)建和銷(xiāo)毀時(shí)間。長(zhǎng)時(shí)間的大量并發(fā)線程掛起,不僅CPU要做實(shí)時(shí) 任務(wù)切換 ,其整體物理資源都將一步步被 蠶食 ,直至最后程序崩潰。 在早期的網(wǎng)絡(luò)編程中,采取阻塞I/O模型來(lái)編寫(xiě)分布式應(yīng)用,唯一能做性能優(yōu)化只有采取傳統(tǒng)的 硬件式堆機(jī) 。在付出高昂的硬件成本開(kāi)銷(xiāo)時(shí),其項(xiàng)目的維護(hù)性也令開(kāi)發(fā)人員頭痛。而且在實(shí)際的開(kāi)發(fā)過(guò)程中,大部分開(kāi)發(fā)人員會(huì)選擇將項(xiàng)目部署在Linux下運(yùn)行。跟Windows 內(nèi)核結(jié)構(gòu) 不同的是,Linux環(huán)境下是沒(méi)有真正意義上的線程概念。其所謂的線程都是采用 進(jìn)程模擬 的方式,也就是 偽線程 。筆者希望大家能夠明白,對(duì)于并發(fā)要求極高的分布式應(yīng)用,一旦采用阻塞IO模型編寫(xiě)就等于自尋死路。

Java的I/O模型由同步I/O和異步I/O構(gòu)成。同步I/O模型包含:阻塞I/O和非阻塞I/O,而在Windows環(huán)境下只要調(diào)用了IOCP的I/O模型,就是真正意義上的異步I/O。

Java的I/O模型示例圖:

筆者帶你剖析Java7.x新特性

?

IOCP(Input/Outut Completion Port,輸入/輸出完成端口)簡(jiǎn)單來(lái)說(shuō)是一種 系統(tǒng)級(jí) 高性能 異步I/O模型。應(yīng)用程序中所有的I/O操作將全部 委托 給操作系統(tǒng)線程去執(zhí)行,直至最后通知并返回結(jié)果。Java7.x對(duì)IOCP進(jìn)行了 深度封裝 ,這使得開(kāi)發(fā)人員可以使用IOCP API編寫(xiě)高效的分布式應(yīng)用。當(dāng)然IOCP 僅限 于使用在Windows平臺(tái),因而無(wú)法在Linux平臺(tái)上使用它(Linux平臺(tái)上可以通過(guò)Epoll模擬IOCP實(shí)現(xiàn))。

?

提示

有過(guò)網(wǎng)絡(luò)編程經(jīng)驗(yàn)的開(kāi)發(fā)人員都應(yīng)該明白,在Windows平臺(tái)下性能最好的I/O模型是IOCP,Linux平臺(tái)下則是EPOLL。但是EPOLL并不算真正意義上的異步I/O,EPOLL只是在盡可能的 模擬 IOCP而已。因?yàn)榘凑誙nix網(wǎng)絡(luò)編程的劃分,多路復(fù)用I/O仍然屬于同步I/O模型,也就是說(shuō)EPOLL其實(shí)是屬于多路復(fù)用I/O。

簡(jiǎn)單來(lái)說(shuō)異步I/O的特征必須滿足如下2點(diǎn):

1、I/O請(qǐng)求與I/O操作不會(huì)阻塞;

2、并非程序自身完成I/O操作,由操作系統(tǒng)線程處理實(shí)際的I/O操作,直至最后通知并返回結(jié)果;

?

早在Java4.x的時(shí)候,NIO(Java New Input/Output,Java新輸入/輸出)的出現(xiàn),使得開(kāi)發(fā)人員可以徹底從阻塞I/O的 噩夢(mèng) 中掙脫出來(lái)。但編寫(xiě)NIO的成本較大,學(xué)習(xí)難度也比較高,使得諸多開(kāi)發(fā)人員望而卻步(目前比較成熟的NIO Frameworks有:Mina、 Netty )。但理解非阻塞I/O的原理還是非常有必要,先來(lái)觀察下述采用阻塞I/O模式編寫(xiě)的分布式應(yīng)用示例:

      @Test
public void testServer() {
	try {
		ServerSocket server = new ServerSocket(8888);
		Socket clist = server.accept();
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				clist.getInputStream()));
		
		/* 未收到I/O請(qǐng)求時(shí)阻塞 */
		System.out.println(reader.readLine());
	} catch (Exception e) {
		e.printStackTrace();
	}
}
    

??

I/O的工作內(nèi)容我們可以根據(jù)其 性質(zhì) 劃分為2部分:I/O請(qǐng)求和I/O操作。上述程序示例我們采用的是阻塞I/O模型,可以很明確的發(fā)現(xiàn)當(dāng)客戶端成功握手服務(wù)端后,如果服務(wù)端并沒(méi)有收到客戶端的I/O請(qǐng)求,服務(wù)端會(huì)在reader.readLine()方法處阻塞。直到成功接收到I/O請(qǐng)求后,服務(wù)端才會(huì)開(kāi)始執(zhí)行實(shí)際的I/O操作。運(yùn)用阻塞I/O模式進(jìn)行分布式編程,為了保證服務(wù)端與客戶端集合的成功會(huì)話,我們不得不為每一條客戶端連接都開(kāi)辟獨(dú)立的線程執(zhí)行I/O操作。當(dāng)然在實(shí)際的開(kāi)發(fā)過(guò)程中,或許已經(jīng)沒(méi)有開(kāi)發(fā)人員會(huì)做這么 荒唐 的事情了。

非阻塞I/O和阻塞I/O最大的不同在于,非阻塞I/O并不會(huì)在I/O請(qǐng)求時(shí)產(chǎn)生阻塞。也就是說(shuō)如果服務(wù)端沒(méi)有收到I/O請(qǐng)求時(shí),非阻塞I/O會(huì) 持續(xù)輪循 I/O請(qǐng)求,當(dāng)有請(qǐng)求進(jìn)來(lái)后就開(kāi)始執(zhí)行I/O操作并 阻塞請(qǐng)求進(jìn)程 。Java7.x允許開(kāi)發(fā)人員使用IOCP API進(jìn)行異步I/O編程,這使得開(kāi)發(fā)人員不必再關(guān)心I/O 是否阻塞 。因?yàn)閼?yīng)用程序中所有的I/O操作將全部 委托 給操作系統(tǒng)線程去執(zhí)行,直至最后通知并返回結(jié)果。

?

九、Swing Framework(JSR 296規(guī)范)支持

筆者其實(shí)對(duì)Swing 非常厭惡 ,如果可以的話筆者希望Oracle能夠 廢除 掉Swing這項(xiàng)技術(shù)。早在08年的時(shí)候筆者由于項(xiàng)目需要,曾飽受Swing的折磨。 繁瑣的布局、組件加載優(yōu)化、冗長(zhǎng)代碼維護(hù) 這些令人痛苦和發(fā)指的問(wèn)題,筆者相信使用過(guò)Swing的人開(kāi)發(fā)人員都能發(fā)出相同的感嘆。

早期的Java GUI(圖形用戶界面)主要由AWT技術(shù)主導(dǎo),但隨著用戶對(duì) 胖客戶端 技術(shù)的豐富度要求逐漸提高,AWT主鍵逐漸被Swing替代。Swing其實(shí)繼承于AWT,并提供有更加絢麗的視圖組件效果。何況相對(duì)于 重量級(jí) 的AWT組件來(lái)說(shuō),Swing顯得更加 輕量

筆者剛才說(shuō)過(guò),Swing雖然相對(duì)于AWT來(lái)說(shuō)組件內(nèi)容更加豐富,但仍然掩蓋不了其 繁瑣 的操作實(shí)現(xiàn)。如果對(duì)組件性能有過(guò)高要求,或者需要實(shí)現(xiàn)快速開(kāi)發(fā),筆者更建議你使用SWT或者JFace技術(shù)( 無(wú)需指望使用IDE工具進(jìn)行可視化編程,因?yàn)檫@純粹是吃力不討好 )。因?yàn)檫@2種技術(shù)可以看成是Swing的過(guò)渡,且相對(duì)Swing來(lái)說(shuō)性能和豐富度更加優(yōu)秀。

既然Java7.x對(duì)Swing仍不忘眷顧優(yōu)化,那希望大家還是支持一下吧。從官方聲明可以看出,JSR 296規(guī)范的目標(biāo)是簡(jiǎn)化Swing的開(kāi)發(fā)難度,且提供有更加豐富的組件資源。如果對(duì)于從未接觸過(guò)Swing編程的開(kāi)發(fā)人員,筆者倒是建議你嘗試一下,或許你并不反感。

?

十、JVM內(nèi)核升級(jí)之Class Loader架構(gòu)調(diào)整

類裝載器(Class Loader)屬于JVM體系結(jié)構(gòu)的重要 組成部分 ,它是將Java類型裝載進(jìn)JVM內(nèi)部的 關(guān)鍵一環(huán) 。它使得Java類型可以動(dòng)態(tài)的被裝載到JVM內(nèi)部解釋并運(yùn)行。
在JVM內(nèi)部存在著2種類型的類裝載器:非自定義類裝載器和自定義類裝載器 。非自定義類裝載器負(fù)責(zé)裝載Java API中的類型及Java程序中的類型,而自定義類裝載器能夠使用自定義的方式來(lái)裝載其類型。不同類型的類裝載器所裝載的類型將被存放于JVM內(nèi)部不同的 命名空間 中。
非自定義類裝載器由JVM內(nèi)部3個(gè)核心類裝載器構(gòu)成:
1、BootStrap ClassLoader;
2、ExtClassLoader;
3、AppClassLoader;

?

BootStrap ClassLoader也稱為 啟動(dòng)類裝載器 ,它是JVM內(nèi)部最 頂層 的類裝載器。BootStrap ClassLoader主要負(fù)責(zé)裝載核心Java API中的類型。ExtClassLoader負(fù)責(zé)裝載擴(kuò)展目錄下的類型。AppClassLoader則負(fù)責(zé)裝載ClassPath(Java應(yīng)用類路徑)下指定的所有類型。其中ExtClassLoader和AppClassLoader都屬于BootStrap ClassLoader的 派生 類裝載器。

在Object內(nèi)部封裝著一個(gè)通過(guò)JNI(Java Native Interface,Java本地接口)方式調(diào)用的getClass()本地方法,該方法返回一個(gè)Class類型。對(duì)于開(kāi)發(fā)人員而言,允許直接調(diào)用其getClassLoader()方法獲取類裝載器實(shí)例。

使用getClassLoader()方法獲取類裝載器:

      @Test
public void testClassLoader() throws Exception {
	/* BootStrap ClassLoader裝載Java API中的類型 */
	ClassLoader loader = System.class.getClassLoader();
	System.out.println(null != loader ? loader.getClass().getName()
			: loader);

	/* ExtClassLoader裝載擴(kuò)展目錄下的類型 */
	System.out.println(CollationData_ar.class.getClassLoader().getClass()
			.getName());

	/* AppClassLoader裝載ClassPath下指定的所有類型 */
	System.out.println(this.getClass().getClassLoader().getClass()
			.getName());
}
    

?

通過(guò)上述程序示例我們可以看出,System類型是被BootStrap ClassLoader所裝載的。但程序的輸出結(jié)果卻是Null,當(dāng)然這并不代表BootStrap ClassLoader不存在。因?yàn)锽ootStrap ClassLoader 不是采用Java語(yǔ)言編寫(xiě) ,而是由C++語(yǔ)言編寫(xiě)并 嵌入 在JVM內(nèi)部,所以開(kāi)發(fā)人員無(wú)法獲取其實(shí)例。CollationData_ar類型屬于jre\lib\ext目錄下的派生類,由ExtClassLoader裝載。當(dāng)前類則由AppClassLoader負(fù)責(zé)裝載。
在此筆者要提示大家,ExtClassLoader和AppClassLoader都是采用Java語(yǔ)言編寫(xiě)。所以ExtClassLoader和AppClassLoader 本身也都是Java類型 ,都會(huì)被最頂層的類裝載器BootStrap ClassLoader裝載,最后才會(huì)裝載各自管轄范圍內(nèi)的類型。
談到ClassLoader的架構(gòu),我們不得不提及 雙親委派模型 。在JVM內(nèi)部,類裝載器裝載類型所采用的便是雙親委派模型機(jī)制。比如AppClassLoader需要將一個(gè)類型裝載進(jìn)JVM內(nèi)部,首先其自身并不會(huì)立即裝載,而是將目標(biāo)類型 委派 給上一級(jí),也就是ExtClassLoader。ExtClassLoader接著再繼續(xù)委派給BootStrap ClassLoader。在JVM內(nèi)部最頂層的類裝載器就是BootStrap ClassLoader,首先由它負(fù)責(zé)裝載目標(biāo)類型及其關(guān)聯(lián)或依賴的所有類型。如果BootStrap ClassLoader裝載失敗,則退回給ExtClassLoader裝載。如果ExtClassLoader也無(wú)法裝載,最后只能退回給AppClassLoader繼續(xù)裝載。最后當(dāng)AppClassLoader都無(wú)法裝載的時(shí)候,便會(huì)拋出ClassNotFoundException異常( 開(kāi)發(fā)人員可以在捕獲ClassNotFoundException異常的時(shí)候重寫(xiě)ClassLoder類型的findClass()方法實(shí)現(xiàn)自定義類型裝載 )。

類裝載器架構(gòu)示例:

筆者帶你剖析Java7.x新特性

?

類裝載器除了需要負(fù)責(zé)類型的裝載,還需要負(fù)責(zé)驗(yàn)證目標(biāo)類型的正確性、屬性內(nèi)存分配、解析符號(hào)引用等操作。JVM通過(guò)裝載、連接和初始化一個(gè)Java類型,使其可以被運(yùn)行時(shí)的Java應(yīng)用程序所使用。其中裝載就是把二進(jìn)制形式的Java類型 寫(xiě)入 進(jìn) JVM內(nèi)部。連接則是把已經(jīng)寫(xiě)入進(jìn)JVM中的二進(jìn)制形式的類型 合并 到JVM的運(yùn)行時(shí)狀態(tài)中去。然而連接階段又分成了3個(gè)步驟:驗(yàn)證、準(zhǔn)備和解析。“驗(yàn)證”步驟確保了Java類型的數(shù)據(jù)格式,“準(zhǔn)備”步驟則負(fù)責(zé)為目標(biāo)類型分配所需的內(nèi)存空間,“解析”步驟負(fù)責(zé)把常量池中的符號(hào)引用轉(zhuǎn)換為直接使用。“驗(yàn)證”和“解析”這2個(gè)步驟都是為最后的初始化工作做準(zhǔn)備。

類型生命周期示例:

筆者帶你剖析Java7.x新特性

?

Java7.x在上述ClassLoader架構(gòu)的基礎(chǔ)之上,進(jìn)行了一些細(xì)微 調(diào)整 。在早期開(kāi)發(fā)人員如果想要實(shí)現(xiàn)自定義類裝載器,恐怕只能實(shí)現(xiàn)ClassLoader類型并重寫(xiě)其findClass()方法。但由于findClass()方法是按照 串行 結(jié)構(gòu) 的方式執(zhí)行, 或許是出于對(duì)性能和安全的考慮 。Java7.x提供了一個(gè)擁有并行執(zhí)行能力的增強(qiáng)實(shí)現(xiàn),這樣一來(lái)自定義類裝載器便可以通過(guò) 異步 方式對(duì)類型進(jìn)行裝載。

?

提示

關(guān)于自定義類裝載器本章筆者將不再繼續(xù)講解,如果有興趣的朋友可以以郵件的形式告知筆者,筆者會(huì)為你提供幫助。

?

本章內(nèi)容到此結(jié)束,由于時(shí)間倉(cāng)庫(kù),本文或許有很多不盡人意的地方,希望各位能夠理解和體諒。關(guān)于下一章的內(nèi)容,筆者打算繼續(xù)講解SSJ的相關(guān)內(nèi)容。

筆者帶你剖析Java7.x新特性


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 亚洲码专区 | bt日韩| 国产在线精彩视频 | 欧美日一区二区三区 | 色狠狠婷婷97| 日本免费不卡一区二区 | 2020天天狠天天透天干天天怕 | 国产精品久久国产精品 | 日韩在线国产 | 欧美精品久久一区 | abc欧美成人影院 | 色综合天天综合中文网 | 欧美黄色一区 | 欧美精品一区二区在线观看 | 亚洲日韩视频免费观看 | 午夜寂寞少妇aaa片毛片 | 清清草免费视频 | 免费一级欧美片片线观看 | 日本一级特黄视频 | 婷婷精品国产亚洲AV在线观看 | 午夜一级毛片 | 香蕉成人啪国产精品视频综合网 | 91麻豆国产极品在线观看洋子 | 人人狠狠综合88综合久久 | 991av| 丁香六月综合网 | 国产精品成人一区二区三区 | 三上悠亚2022最新新作番号 | 男生日女生免费视频 | 天天天天天天操 | 咪咪色在线视频 | 国产精品视频在线观看 | 欧美freexx| 天天操中文字幕 | 国产精品一区二区三区久久 | 国产tv| 亚欧精品一区二区三区四区 | 欧美高清免费 | 久久国产一区二区 | 精品国内视频 | 日韩a级一片 |