国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

07-避免使用終結(jié)方法

2019-11-08 18:49:13
字體:
供稿:網(wǎng)友

本條目大意

盡量避免在類中使用終結(jié)(finalize)方法,在里面寫一些釋放類中資源的語句。


為什么要避免使用 finalize方法?

1、java語言規(guī)范不僅不保證 finalize方法會被及時地執(zhí)行,而且根本不保證他們會被執(zhí)行。 2、System.gc 和 System.runFinalization 這兩個方法只是增加了finalizer 方法被執(zhí)行的機會。 3、唯一能保證 finalize 方法被執(zhí)行的方法有兩個,System.runFinalizersOnExit 和 Runtime.runFinalizersOnExit ,但是這兩個方法已經(jīng)被廢棄。 4、覆蓋并使用終結(jié)方法會有嚴重的性能損失。 5、及時地執(zhí)行終結(jié)方法是垃圾回收算法的一個主要功能,但是在不同的JVM實現(xiàn)中會大相庭徑,使用終結(jié)方法可能會喪失平臺無關(guān)性。


如果類的對象中封裝的資源確實需要進行釋放,我們應(yīng)該怎么做呢?

一般來說,需要釋放資源的有線程或者文件還有涉及到本地資源的對象。

我們不去覆蓋 finalize 方法,而是自己提供一個顯式的終止資源的方法。比如 java.io.FileInputStream 的close 方法。當使用完這個FileInputStream對象時,顯式調(diào)用close() 來回收資源。

我們首先看看 FileInputStream 是怎么玩的:

public void close() throws IOException { synchronized (closeLock) { if (closed) { return; } closed = true; } if (channel != null) { fd.decrementAndGetUseCount(); channel.close(); } int useCount = fd.decrementAndGetUseCount(); if ((useCount <= 0) || !isRunningFinalize()) { close0(); }}

要求此類的使用者不再使用此類的時候調(diào)用 close 終止方法,進行釋放資源,并且在類中添加一個 closed 來標記資源是否已經(jīng)釋放,如果已經(jīng)被釋放了,那此類中的方法如果再被調(diào)用的話就拋出異常。

抽象形式如下:

class MyObject{ PRivate boolean isClosed = false; //終止方法 public void close(){ //資源釋放操作... isClosed = true; }}public static void main(String... args) { MyObject object = new MyObject(); try{ //在這里使用調(diào)用方法... } finally { //在這里關(guān)閉 object.close(); }}

終結(jié)方法的用途

再繼續(xù)往下看,就會看到 FileInputStream 還是有覆蓋 finalize方法的。

protected void finalize() throws IOException { if ((fd != null) && (fd != FileDescriptor.in)) { runningFinalize.set(Boolean.TRUE); try { close(); } finally { runningFinalize.set(Boolean.FALSE); } }}

清楚的看到方法里面進行調(diào)用了 close 方法,這是為了當對象持有者忘記調(diào)用前面段落中建議的顯式終結(jié)方法 :close()的情況下,使用inalize 方法充當“安全網(wǎng)”這是終結(jié)方法是用途之一。

抽象形式如下:

class MyObject{ private boolean isClosed = false; //終止方法 public void close(){ //資源釋放操作... isClosed = true; } //安全網(wǎng) protected void finalize() throws Throwable { try{ close(); } finally { super.finalize(); } }}

終結(jié)方法還有一個好處,把終結(jié)方法放在一個匿名的類,該匿名類的唯一用途就是終結(jié)它的外圍實例。 外圍實例持有對終結(jié)方法守衛(wèi)者的唯一實例,這意味著當外圍實例是不可達時,這個終結(jié)方法守衛(wèi)者也是不可達的了,垃圾回收器回收外圍實例的同時也會回收終結(jié)方法守衛(wèi)者的實例,而終結(jié)方法守衛(wèi)者的finalize方法就把外圍實例的資源釋放掉,就好像是終結(jié)方法是外圍實例的一個方法一樣。

看看 java.util.Timer 的終結(jié)方法守衛(wèi)者:

public void cancel() { synchronized(queue) { thread.newTasksMayBeScheduled = false; queue.clear(); queue.notify(); // In case queue was already empty. }}private final Object threadReaper = new Object() { protected void finalize() throws Throwable { synchronized(queue) { thread.newTasksMayBeScheduled = false; queue.notify(); // In case queue is empty. } }};

cancel 方法是 Timer 提供的顯式終止方法,threadReaper 是一個私有變量,保證除了實例本身外沒有對它的引用,它覆蓋 finalize 方法,實現(xiàn)與 cancel 方法一樣的功能。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 乐安县| 始兴县| 陇南市| 曲周县| 昭苏县| 西藏| 紫阳县| 蒙阴县| 从江县| 三河市| 沁源县| 喀喇沁旗| 阿鲁科尔沁旗| 远安县| 赤水市| 聊城市| 辽宁省| 宣城市| 嘉义市| 南乐县| 祁东县| 合山市| 如东县| 河北省| 黎川县| 昭苏县| 阳原县| 沾化县| 剑阁县| 荔波县| 敦煌市| 四会市| 钟祥市| 准格尔旗| 深水埗区| 昭通市| 南华县| 盐山县| 克东县| 宁化县| 武川县|