<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Picses' sky

    Picses' sky
    posts - 43, comments - 29, trackbacks - 0, articles - 24

    用Java線程獲取優異性能(I)1

    Posted on 2007-07-18 13:11 Matthew Chen 閱讀(235) 評論(0)  編輯  收藏 所屬分類: Java MultiThread
    摘要
    用戶期望程序能展現優異的性能。為了滿足這個期望,你的程序常常使用到線程。在這篇文章中我們開始練習使用線程。你將學習到線程、線程類及Runnable。
    用戶不喜歡反應遲鈍的軟件。當用戶單擊一個鼠標時,他們希望程序立即回應他們的請求,即使程序正處于費時的運行之中,比如為一篇很長的文檔重編頁碼或等待一個網絡操作的完成。對用戶響應很慢的程序其性能拙劣。為提高程序性能,開發者一般使用線程。
    這篇文章是探索線程的第一部份。雖然你可能認為線程是一種難于掌握的事物,但我打算向你顯示線程是易于理解的。在這篇文章中,我將向你介紹線程和線程類,以及討論Runnable。此外,在后面的文章中,我將探索同步(通過鎖),同步的問題(比如死鎖),等待/通知機制,時序安排(有優先權和沒有優先權),線程中斷,計時器,揮發性,線程組和線程本地變量。
    閱讀關于線程設計的整個系列:
    ·第1部份:介紹線程和線程類,以及Runnable
    ·第2部份:使用同步使線程串行化訪問關鍵代碼部份
    注意
    這篇文章及其應用程序的三個相關線程練習與applets不同。然而,我在應用程序中介紹的多數應用到applets。主要不同的是:為了安全的原因,不是所有的線程操作都可以放到一個applet中(我將在以后的文章中討論applets)。
    什么是線程?
    線程的概念并不難于掌握:它是程序代碼的一個獨立的執行通道。當多個線程執行時,經由相同代碼的一個線程的通道通常與其它的不同。例如,假設一個線程執行一段相當于一個if-else語句的if部分的字節代碼時,而另一個線程正執行相當于else部分的字節代碼。JVM怎樣保持對于每一個線程執行的跟蹤呢?JVM給每一個線程它自己的方法調用堆棧。另外跟蹤當前指令字節代碼,方法堆棧跟蹤本地變量,JVM傳遞給一個方法的參數,以及方法的返回值。
    當多個線程在同一個程序中執行字節代碼序列時,這種行為叫作多線程。多線程在多方面有利于程序:
    ·當執行其它任務時多線程GUI(圖形用戶界面)程序仍能保持對用戶的響應,比如重編頁碼或打印一個文檔。
    ·帶線程的程序一般比它們沒有帶線程的副本程序完成得快。這尤其表現在線程運行在一個多處理器機器上,在這里每一個線程都有它自己的處理器。
    Java通過java.lang.Thread類完成多線程。每一個線程對象描述一個單獨的執行線程。那些運行發生在線程的run()方法中。因為缺省的run()方法什么都不做,你必須創建Thread子類并重載run()以完成有用的工作。練習列表1中領略一個在Thread中的線程及多線程:
    列表1. ThreadDemo.java
    // ThreadDemo.java
    class ThreadDemo
    {
    public static void main (String [] args)
    {
    MyThread mt = new MyThread ();
    mt.start ();
    for (int i = 0; i < 50; i++)
    System.out.println ("i = " + i + ", i * i = " + i * i);
    }
    }
    class MyThread extends Thread
    {
    public void run ()
    {
    for (int count = 1, row = 1; row < 20; row++, count++)
    {
    for (int i = 0; i < count; i++)
    System.out.print ('*');
    System.out.print ('\n');
    }
    }
    }
    列表1顯示了一個由類ThreadDemo和MyThread組成的應用程序的源代碼。類ThreadDemo通過創建一個MyThread對象驅動應用程序,開始一個與其對象相關的線程并執行一段打印一個正方形表的代碼。相反, MyThread重載Thread的run()方法打印(通過標準輸入流)一個由星形符號組成的直角三角形。
    當你鍵入java ThreadDemo運行應用程序時, JVM創建一個運行main()方法的開始線程。通過執行mt.start (),開始線程告訴JVM創建一個執行包含MyThread對象的run()方法的字節代碼指令的第二個線程。當start()方法返回時,開始線程循環執行打印一個正方形表,此時另一個新線程執行run()方法打印直角三角形。
    輸出會象什么樣呢?運行ThreadDemo就可以看到。你將注意到每一個線程的輸出與其它線程的輸出相互交替。這樣的結果是因為兩個線程將它們的輸出都發送到了同樣的標準輸出流。
    注意
    多數(不是所有)JVM設備使用下層平臺的線程性能。因為那些性能是平臺特有的,你的多線程程序的輸出順序可能與一些人的其他輸出的順序不一樣。這種不同是由于時序的安排,我將在這一系列的稍后探討這一話題。
    線程類
    要精通寫多線程代碼,你必須首先理解創建Thread類的多種方法。這部份將探討這些方法。明確地說,你將學到開始線程的方法,命名線程,使線程休眠,決定一個線程是否激活,將一個線程與另一個線程相聯,和在當前線程的線程組及子組中列舉所有激活的線程。我也會討論線程調試輔助程序及用戶線程與監督線程的對比。
    我將在以后的文章中介紹線程方法的余下部份,Sun不贊成的方法除外。
    警告
    Sun有一些不贊成的線程方法種類,比如suspend()和resume(),因為它們能鎖住你的程序或破壞對象。所以,你不必在你的代碼中調用它們。考慮到針對這些方法工作區的SDK文件,在這篇文章中我沒有包含這些方法。
    構造線程
    Thread有八個構造器。最簡單的是:
    ·Thread(),用缺省名稱創建一個Thread對象
    ·Thread(String name),用指定的name參數的名稱創建一個Thread對象
    下一個最簡單的構造器是Thread(Runnable target)和Thread(Runnable target, String name)。 除Runnable參數之外,這些構造器與前述的構造器一樣。不同的是:Runnable參數識別提供run()方法的線程之外的對象。(你將在這篇文章稍后學到Runnable。)最后幾個構造器是Thread(String name),Thread(Runnable target),和Thread(Runnable target, String name)。然而,最后的構造器包含了一個為了組織意圖的ThreadGroup參數。
    最后四個構造器之一,Thread(ThreadGroup group, Runnable target, String name, long stackSize),令人感興趣的是它能夠讓你指定想要的線程方法調用堆棧的大小。能夠指定大小將證明在使用遞歸方法(一種為何一個方法不斷重復調用自身的技術)優美地解決一些問題的程序中是十分有幫助的。通過明確地設置堆棧大小,你有時能夠預防StackOverflowErrors。然而,太大將導致OutOfMemoryErrors。同樣,Sun將方法調用堆棧的大小看作平臺依賴。依賴平臺,方法調用堆棧的大小可能改變。因此,在寫調用Thread(ThreadGroup group, Runnable target, String name, long stackSize)代碼前仔細考慮你的程序分枝。
    開始你的運載工具
    線程類似于運載工具:它們將程序從開始移動到結束。Thread 和Thread子類對象不是線程。它們描述一個線程的屬性,比如名稱和包含線程執行的代碼(經由一個run()方法)。當一個新線程執行run()時,另一個線程正調用Thread或其子類對象的start()方法。例如,要開始第二個線程,應用程序的開始線程—它執行main()—調用start()。作為響應,JVM和平臺一起工作的線程操作代碼確保線程正確地初始化并調用Thread或其子類對象的run()方法。
    一旦start()完成,多重線程便運行。因為我們趨向于在一種線性的方式中思維,我們常發現當兩個或更多線程正運行時理解并發(同時)行為是困難的。因此,你應該看看顯示與時間對比一個線程正在哪里執行(它的位置)的圖表。下圖就是這樣一個圖表。

    與時間對比一個開始線程和一個新建線程執行位置的行為

    圖表顯示了幾個重要的時間段:
    ·開始線程的初始化
    ·線程開始執行main()瞬間
    ·線程開始執行start()的瞬間
    ·start()創建一個新線程并返回main()的瞬間
    ·新線程的初始化
    ·新線程開始執行run()的瞬間
    ·每個線程結束的不同瞬間
    注意新線程的初始化,它對run()的執行,和它的結束都與開始線程的執行同時發生。
    警告
    一個線程調用start()后,在run()方法退出前并發調用那方法將導致start()擲出一個java.lang.IllegalThreadStateException對象。
    主站蜘蛛池模板: 亚洲区小说区激情区图片区| 成人免费午夜视频| 亚洲日本va中文字幕久久| 亚洲国产成人AV网站| 国产男女猛烈无遮挡免费网站| 亚洲夂夂婷婷色拍WW47| 免费的一级黄色片| 朝桐光亚洲专区在线中文字幕 | 国产男女爽爽爽爽爽免费视频| 亚洲国产精品久久久久网站| 无码精品国产一区二区三区免费 | 成年午夜视频免费观看视频| 亚洲中文字幕无码久久| 国产a不卡片精品免费观看| 一级毛片免费全部播放| 国产精品亚洲片在线| 69视频在线观看免费| 亚洲国产视频久久| 国产成人免费手机在线观看视频| 免费一区二区无码视频在线播放| 狠狠亚洲狠狠欧洲2019| 久久ww精品w免费人成| 亚洲色欲色欲www在线播放| 夜色阁亚洲一区二区三区| 99久久99这里只有免费的精品 | 久久香蕉国产线看观看亚洲片| 91青青青国产在观免费影视| 亚洲最大成人网色香蕉| 又粗又硬又黄又爽的免费视频 | 又粗又黄又猛又爽大片免费| CAOPORN国产精品免费视频| 亚洲精品视频免费在线观看| 真实乱视频国产免费观看| 男女一边摸一边做爽的免费视频 | 亚洲色av性色在线观无码| 精品久久久久成人码免费动漫| 精品国产日韩亚洲一区91 | 中文字幕亚洲精品资源网| 国产精品免费视频网站| 成人无码a级毛片免费| 亚洲人成人无码.www石榴|