小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

EventQueue.invokeLater(new Runnable())

 哥只是個(gè)傳說 2013-11-28

java.awt
類 EventQueue

java.lang.Object
  繼承者 java.awt.EventQueue
public class EventQueue
extends Object

EventQueue 是一個(gè)與平臺(tái)無關(guān)的類,它將來自于底層同位體類和受信任的應(yīng)用程序類的事件列入隊(duì)列。

它封裝了異步事件指派機(jī)制,該機(jī)制從隊(duì)列中提取事件,然后通過對(duì)此 EventQueue 調(diào)用 dispatchEvent(AWTEvent) 方法來指派這些事件(事件作為參數(shù)被指派)。該機(jī)制的特殊行為是與實(shí)現(xiàn)有關(guān)的。指派實(shí)際排入到該隊(duì)列中的事件(注意,正在發(fā)送到 EventQueue 中的事件可以被合并)的唯一要求是:

按順序指派。
也就是說,不允許同時(shí)從該隊(duì)列中指派多個(gè)事件。
指派順序與它們排隊(duì)的順序相同。
也就是說,如果 AWTEvent A 比 AWTEvent B 先排入到 EventQueue 中,那么事件 B 不能在事件 A 之前被指派。

一些瀏覽器將不同代碼基中的 applet 分成獨(dú)立的上下文,并在這些上下文之間建立一道道墻。在這樣的場(chǎng)景中,每個(gè)上下文將會(huì)有一個(gè) EventQueue。其他瀏覽器將所有的 applet 放入到同一個(gè)上下文中,這意味著所有 applet 只有一個(gè)全局 EventQueue。該行為是與實(shí)現(xiàn)有關(guān)的。有關(guān)更多信息,請(qǐng)參照瀏覽器的文檔。 

invokeLater

public static void invokeLater(Runnable runnable)
導(dǎo)致 runnablerun 方法在 the system EventQueue 的指派線程中被調(diào)用。
參數(shù):
runnable - Runnable 對(duì)象,其 run 方法應(yīng)該在 EventQueue 上同步執(zhí)行
從以下版本開始:
1.2
另請(qǐng)參見:
invokeAndWait(java.lang.Runnable)
========================================================================

七嘴八舌:

使用該方式的原因是:awt是單線程模式的,所有awt的組件只能在(推薦方式)事件處理線程中訪問,從而保證組件狀態(tài)的可確定性。

---------------------------------------------------------------------------------------

 

使用eventqueue.invokelater()好處是顯而易見的,這個(gè)方法調(diào)用完畢后,它會(huì)被銷毀,因?yàn)槟涿麅?nèi)部類是作為臨時(shí)變量存在的,給它分配的內(nèi)存在此時(shí)會(huì)被釋放。這個(gè)對(duì)于只需要在一個(gè)地方使用時(shí)可以節(jié)省內(nèi)存,而且這個(gè)類是不可以被其它的方法或類使用的,只能被EventQueue.invokeLater()來使用。但如果你需要一個(gè)在很多地方都能用到的類,而不是只在某一個(gè)類里面或者方法里用的話,定義成匿名內(nèi)部類顯然是不可取的。 是,runnable是跟線程相關(guān)的類。

swingutilities.invokelater()和eventqueue.invokelater(),后者可以不干擾到事件分發(fā)線程.SwingUtilities版只是一個(gè)薄薄的封裝方法,它直接轉(zhuǎn)而調(diào)用 EventQueue.invokeLater。因?yàn)镾wing框架本身經(jīng)常調(diào)用SwingUtilities,使用SwingUtilities可以減少程序引入的類。

-----------------------------------------------------------------------------------------------------------------------------

實(shí)戰(zhàn)JAVA內(nèi)存泄露問題http://www./kf/201109/104277.html

一個(gè)J2EE產(chǎn)品在生產(chǎn)環(huán)境下出現(xiàn)了內(nèi)存泄露

 

在內(nèi)存比較大的時(shí)候,生成一個(gè)heap dump,打開來看什么對(duì)象占內(nèi)存最多,發(fā)現(xiàn)下面這個(gè)類的對(duì)象占了大量的內(nèi)存


Java.awt.EventQueueItem


找到代碼里面用到這個(gè)類的地方,發(fā)現(xiàn)有大概如下的代碼

 

我們實(shí)現(xiàn)的一個(gè)OnProcess函數(shù)里面真正做事件處理;

// 過程好像比較糾結(jié),第三方是個(gè)外國公司,我們公司的這段代碼之前也是老外寫的,我也還沒搞明白為什么通知和處理要分開,直接想辦法做成處理不就可以了么?!

onEventNofity(***)
{

java.awt.EventQueue.invokeLater(new Runnable(){
public void run() {
doProcess();
}
});

}這段代碼肯定是有問題,這個(gè)invokelater里面代碼看進(jìn)去是用新生成的Runnable對(duì)象構(gòu)造了一個(gè)java.awt.event.InvocationEvent對(duì)象,然后會(huì)放到系統(tǒng)有一個(gè)默認(rèn)的java.awt.EventQueue實(shí)現(xiàn)對(duì)象里面,然后讓一個(gè)java.awt. EventDispatchThread調(diào)度,然后一個(gè)一個(gè)執(zhí)行這里的run方法;

首先相當(dāng)于每次一個(gè)事件過來的時(shí)候就生成一個(gè)Runnable對(duì)象,進(jìn)而生成InvocationEvent對(duì)象,占用了大量的內(nèi)存,

可糾結(jié)的是為啥以前沒問題?而且這個(gè)版本在我們開發(fā)服務(wù)器上跑了幾個(gè)月現(xiàn)在還一直正常;

中間經(jīng)過各個(gè)環(huán)境下的測(cè)試、日志分析、對(duì)比,終于慢慢發(fā)現(xiàn),從對(duì)日志的時(shí)間分析看,現(xiàn)在的事件處理速度,就是doProcess這里太慢了,導(dǎo)致事件處理不過來,然后大量的Runnable和InvocationEvent對(duì)象堆積在java.awt.EventQueue里面,導(dǎo)致了內(nèi)存的泄露;

昨天講了內(nèi)存泄露問題的原因其實(shí)就是在下面這段代碼中無緣無故的搞個(gè)java.awt.invokeLater(New Runnable()….,
當(dāng)然,作者本來的用意是好的,其實(shí)就是把收到事件和處理事件做異步化處理,本來的目的也是提高性能里的情況是按照第三方的API,OnEventNotify()需要盡快返回,否則會(huì)堵住后面發(fā)過來的事件;

 

這段代碼的主要兩個(gè)問題:
1. java.awt.invokeLater里面每次會(huì)新生成一個(gè)java.awt.event.InvocationEvent對(duì)象;
2.這里的Runnable的匿名類,其實(shí)本來完全可以單獨(dú)定義的,現(xiàn)在這個(gè)寫法,相當(dāng)于每次一個(gè)事件過來都new出一個(gè)Runnable的匿名類來。。。白白浪費(fèi)了大量內(nèi)存

導(dǎo)致內(nèi)存泄露的情況就是事件現(xiàn)在較多,doProcess占用時(shí)間太長,導(dǎo)致java.awt.event.InvocationEvent對(duì)象大量堆積;
所以,解決思路其實(shí)比較明確,
1. 要么提高處理速度使得事件不堆積,
2. 要么改成其他異步化的方式,避免每次生成java.awt.event.InvocationEvent對(duì)象

在開發(fā)環(huán)境下連接到對(duì)方QA環(huán)境,使得數(shù)據(jù)量保持一致,重現(xiàn)了內(nèi)存泄露問題后,經(jīng)過分析調(diào)試測(cè)試,下面幾種方案都在開發(fā)環(huán)境下運(yùn)行良好,內(nèi)存保持穩(wěn)定,gc日志和heapdump都很正常,解決了內(nèi)存泄露問題:
1. 修改了兩個(gè)第三方API相關(guān)的配置參數(shù),使得doProcess這里處理速度提高了很多,于是即使在現(xiàn)在的事件數(shù)量下,仍然可以避免事件堆積;
2. 由于事件處理是該模塊的核心,而且凡是程序運(yùn)行的時(shí)候必然會(huì)有事件不停的發(fā)送過來,所以,修改代碼如下
onEventNofity(***)
{
//這里改成啥事也不做
}
然后程序起來的時(shí)候開一個(gè)線程不停的去做doProcess的事情;
由于這里onEventNotify僅僅是起個(gè)通知的作用,真正的事件是放在內(nèi)部的另外一個(gè)隊(duì)列里,所以這樣做是可以的;如果有參數(shù)依賴,那可以在這個(gè)onEventNotify調(diào)用其他線程池的方式去做

------------------------------------------------------------------------------------------

 

核桃博客說明:
下面是JDK中java.awt.EventQueue.invokeLater的源代碼

    public static void invokeLater(Runnable runnable) {
        Toolkit.getEventQueue().postEvent(
            new InvocationEvent(Toolkit.getDefaultToolkit(), runnable));
    }這里可以看到,每調(diào)用一次,除了外面自己的new Runnable對(duì)象以外,里面還會(huì)new 一個(gè)InvocationEvent對(duì)象,所以一來這里浪費(fèi)了大量內(nèi)存和CPU時(shí)間,不停的new出東西來;
而來的確正確的做法應(yīng)該是搞個(gè)后臺(tái)線程或者線程池來處理這些事件;

---------------------------------------------------------------------------------------

OK,資料現(xiàn)就這些,大概也了解了是怎么回事,留下備用

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多