<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

    怎樣使用名稱(chēng)
    在一個(gè)調(diào)試會(huì)話(huà)期間,使用用戶(hù)友好方式從另一個(gè)線(xiàn)程區(qū)別其中一個(gè)線(xiàn)程證明是有幫助的。要區(qū)分其中一個(gè)線(xiàn)程,Java給一個(gè)線(xiàn)程取一個(gè)名稱(chēng)。Thread缺省的名稱(chēng)是一個(gè)短線(xiàn)連字符和一個(gè)零開(kāi)始的數(shù)字符號(hào)。你可以接受Java的缺省線(xiàn)程名稱(chēng)或選擇使用你自己的。為了能夠自定義名稱(chēng),Thread提供帶有name參數(shù)和一個(gè)setName(String name)方法的構(gòu)造器。Thread也提供一個(gè)getName()方法返回當(dāng)前名稱(chēng)。表2顯示了怎樣通過(guò)Thread(String name)創(chuàng)建一個(gè)自定義名稱(chēng)和通過(guò)在run()方法中調(diào)用getName()檢索當(dāng)前名稱(chēng):
    表2.NameThatThread.java
    // NameThatThread.java
    class NameThatThread
    {
    public static void main (String [] args)
    {
    MyThread mt;
    if (args.length == 0)
    mt = new MyThread ();
    else
    mt = new MyThread (args [0]);
    mt.start ();
    }
    }
    class MyThread extends Thread
    {
    MyThread ()
    {
    //編譯器創(chuàng)建等價(jià)于super()的字節(jié)代碼
    }
    MyThread (String name)
    {
    super (name); //將名稱(chēng)傳遞給Thread超類(lèi)
    }
    public void run ()
    {
    System.out.println ("My name is: " + getName ());
    }
    }
    你能夠在命令行向MyThread傳遞一個(gè)可選的name參數(shù)。例如,java NameThatThread X 建立X作為線(xiàn)程的名稱(chēng)。如果你指定一個(gè)名稱(chēng)失敗,你將看到下面的輸出:
    My name is: Thread-1
    如果你喜歡,你能夠在MyThread(String name)構(gòu)造器中將super(name)調(diào)用改變成setName(String name)調(diào)用——作為setName(name)后一種方法調(diào)用達(dá)到同樣建立線(xiàn)程名稱(chēng)的目的——作為super(name)我作為練習(xí)保留給你們。
    注意
    Java主要將名稱(chēng)指派給運(yùn)行main() 方法的線(xiàn)程,開(kāi)始線(xiàn)程。你特別要看看當(dāng)開(kāi)始線(xiàn)程擲出一個(gè)例外對(duì)象時(shí)在線(xiàn)程“main”的例外顯示的JVM的缺省例外處理打印消息。
    休眠或停止休眠
    在這一欄后面,我將向你介紹動(dòng)畫(huà)——在一個(gè)表面上重復(fù)畫(huà)圖形,這稍微不同于完成一個(gè)運(yùn)動(dòng)畫(huà)面。要完成動(dòng)畫(huà),一個(gè)線(xiàn)程必須在它顯示兩個(gè)連續(xù)畫(huà)面時(shí)中止。調(diào)用Thread的靜態(tài)sleep(long millis)方法強(qiáng)迫一個(gè)線(xiàn)程中止millis毫秒。另一個(gè)線(xiàn)程可能中斷正在休眠的線(xiàn)程。如果這種事發(fā)生,正在休眠的線(xiàn)程將醒來(lái)并從sleep(long millis)方法擲出一個(gè)InterruptedException對(duì)象。結(jié)果,調(diào)用sleep(long millis)的代碼必須在一個(gè)try代碼塊中出現(xiàn)——或代碼方法必須在自己的throws子句中包括InterruptedException。
    為了示范sleep(long millis),我寫(xiě)了一個(gè)CalcPI1應(yīng)用程序。這個(gè)應(yīng)用程序開(kāi)始了一個(gè)新線(xiàn)程便于用一個(gè)數(shù)學(xué)運(yùn)算法則計(jì)算數(shù)學(xué)常量pi的值。當(dāng)新線(xiàn)程計(jì)算時(shí),開(kāi)始線(xiàn)程通過(guò)調(diào)用sleep(long millis)中止10毫秒。在開(kāi)始線(xiàn)程醒后,它將打印pi的值,其中新線(xiàn)程存貯在變量pi中。表3給出了CalcPI1的源代碼:
    表3. CalcPI1.java
    // CalcPI1.java
    class CalcPI1
    {
    public static void main (String [] args)
    {
    MyThread mt = new MyThread ();
    mt.start ();
    try
    {
    Thread.sleep (10); //休眠10毫秒
    }
    catch (InterruptedException e)
    {
    }
    System.out.println ("pi = " + mt.pi);
    }
    }
    class MyThread extends Thread
    {
    boolean negative = true;
    double pi; //缺省初始化為0.0
    public void run ()
    {
    for (int i = 3; i < 100000; i += 2)
    {
    if (negative)
    pi -= (1.0 / i);
    else
    pi += (1.0 / i);
    negative = !negative;
    }
    pi += 1.0;
    pi *= 4.0;
    System.out.println ("Finished calculating PI");
    }
    }
    如果你運(yùn)行這個(gè)程序,你將看到輸出如下(但也可能不一樣):
    pi = -0.2146197014017295
    完成計(jì)算PI
    為什么輸出不正確呢?畢竟,pi的值應(yīng)近似等于3.14159。回答是:開(kāi)始線(xiàn)程醒得太快了。在新線(xiàn)程剛開(kāi)始計(jì)算pi時(shí),開(kāi)始線(xiàn)程就醒過(guò)來(lái)讀取pi的當(dāng)前值并打印其值。我們可以通過(guò)將10毫秒延遲增加為更長(zhǎng)的值來(lái)進(jìn)行補(bǔ)償。這一更長(zhǎng)的值(不幸的是它是依賴(lài)于平臺(tái)的)將給新線(xiàn)程一個(gè)機(jī)會(huì)在開(kāi)始線(xiàn)程醒過(guò)來(lái)之前完成計(jì)算。(后面,你將學(xué)到一種不依賴(lài)平臺(tái)的技術(shù),它將防止開(kāi)始線(xiàn)程醒來(lái)直到新線(xiàn)程完成。)
    注意
    線(xiàn)程同時(shí)提供一個(gè)sleep(long millis, int nanos)方法,它將線(xiàn)程休眠millis 毫秒和nanos 納秒。因?yàn)槎鄶?shù)基于JVM的平臺(tái)都不支持納秒級(jí)的分解度,JVM 線(xiàn)程處理代碼將納秒數(shù)字四舍五入成毫秒數(shù)字的近似值。如果一個(gè)平臺(tái)不支持毫秒級(jí)的分解度,JVM 線(xiàn)程處理代碼將毫秒數(shù)字四舍五入成平臺(tái)支持的最小級(jí)分解度的近似倍數(shù)。
    它是死的還是活的?
    當(dāng)一個(gè)程序調(diào)用Thread的start()方法時(shí),在一個(gè)新線(xiàn)程調(diào)用run()之前有一個(gè)時(shí)間段(為了初始化)。run()返回后,在JVM清除線(xiàn)程之前有一段時(shí)間通過(guò)。JVM認(rèn)為線(xiàn)程立即激活優(yōu)先于線(xiàn)程調(diào)用run(),在線(xiàn)程執(zhí)行run()期間和run()返回后。在這時(shí)間間隔期間,Thread的isAlive()方法返回一個(gè)布爾真值。否則,方法返回一個(gè)假值。
    isAlive()在一個(gè)線(xiàn)程需要在第一個(gè)線(xiàn)程能夠檢查其它線(xiàn)程的結(jié)果之前等待另一個(gè)線(xiàn)程完成其run()方法的情形下證明是有幫助的。實(shí)質(zhì)上,那些需要等待的線(xiàn)程輸入一個(gè)while循環(huán)。當(dāng)isAlive()為其它線(xiàn)程返回真值時(shí),等待線(xiàn)程調(diào)用sleep(long millis) (或 sleep(long millis, int nanos))周期性地休眠 (避免浪費(fèi)更多的CPU循環(huán))。一旦isAlive()返回假值,等待線(xiàn)程便檢查其它線(xiàn)程的結(jié)果。
    你將在哪里使用這樣的技術(shù)呢?對(duì)于起動(dòng)器,一個(gè)CalcPI1的修改版本怎么樣,在打印pi的值前開(kāi)始線(xiàn)程在哪里等待新線(xiàn)程的完成?表4的CalcPI2源代碼示范了這一技術(shù):
    表4. CalcPI2.java
    // CalcPI2.java
    class CalcPI2
    {
    public static void main (String [] args)
    {
    MyThread mt = new MyThread ();
    mt.start ();
    while (mt.isAlive ())
    try
    {
    Thread.sleep (10); //休眠10毫秒
    }
    catch (InterruptedException e)
    {
    }
    System.out.println ("pi = " + mt.pi);
    }
    }
    class MyThread extends Thread
    {
    boolean negative = true;
    double pi; //缺省初始化成0.0
    public void run ()
    {
    for (int i = 3; i < 100000; i += 2)
    {
    if (negative)
    pi -= (1.0 / i);
    else
    pi += (1.0 / i);
    negative = !negative;
    }
    pi += 1.0;
    pi *= 4.0;
    System.out.println ("Finished calculating PI");
    }
    }
    CalcPI2的開(kāi)始線(xiàn)程在10毫秒時(shí)間間隔休眠,直到mt.isAlive ()返回假值。當(dāng)那些發(fā)生時(shí),開(kāi)始線(xiàn)程從它的while循環(huán)中退出并打印pi的內(nèi)容。如果你運(yùn)行這個(gè)程序,你將看到如下的輸出(但不一定一樣):
    完成計(jì)算PI
    pi = 3.1415726535897894
    這不,現(xiàn)在看上去更精確了?
    注意
    一個(gè)線(xiàn)程可能對(duì)它自己調(diào)用isAlive() 方法。然而,這毫無(wú)意義,因?yàn)閕sAlive()將一直返回真值。
    合力
    因?yàn)閣hile循環(huán)/isAlive()方法/sleep()方法技術(shù)證明是有用的,Sun將其打包進(jìn)三個(gè)方法組成的一個(gè)組合里:join(),join(long millis)和join(long millis, int nanos)。當(dāng)當(dāng)前線(xiàn)程想等待其它線(xiàn)程結(jié)束時(shí),經(jīng)由另一個(gè)線(xiàn)程的線(xiàn)程對(duì)象引用調(diào)用join()。相反,當(dāng)它想其中任意線(xiàn)程等待其它線(xiàn)程結(jié)束或等待直到millis毫秒和nanos納秒組合通過(guò)時(shí),當(dāng)前線(xiàn)程調(diào)用join(long millis)或join(long millis, int nanos)。(作為sleep()方法,JVM 線(xiàn)程處理代碼將對(duì)join(long millis)和join(long millis,int nanos)方法的參數(shù)值四舍五入。)表5的CalcPI3源代碼示范了一個(gè)對(duì)join()的調(diào)用:
    表5. CalcPI3.java
    // CalcPI3.java
    class CalcPI3
    {
    public static void main (String [] args)
    {
    MyThread mt = new MyThread ();
    mt.start ();
    try
    {
    mt.join ();
    }
    catch (InterruptedException e)
    {
    }
    System.out.println ("pi = " + mt.pi);
    }
    }
    class MyThread extends Thread
    {
    boolean negative = true;
    double pi; //缺省初始化成0.0
    public void run ()
    {
    for (int i = 3; i < 100000; i += 2)
    {
    if (negative)
    pi -= (1.0 / i);
    else
    pi += (1.0 / i);
    negative = !negative;
    }
    pi += 1.0;
    pi *= 4.0;
    System.out.println ("Finished calculating PI");
    }
    }
    CalcPI3的開(kāi)始線(xiàn)程等待與MyThread對(duì)象有關(guān)被mt引用的線(xiàn)程結(jié)束。接著開(kāi)始線(xiàn)程打印pi的值,其值與CalcPI2的輸出一樣。
    警告
    不要試圖將當(dāng)前線(xiàn)程與其自身連接,因?yàn)檫@樣當(dāng)前線(xiàn)程將要永遠(yuǎn)等待。

    主站蜘蛛池模板: 亚洲精品资源在线| 91av视频免费在线观看| 亚洲人成电影网站| 亚洲国产综合无码一区| 国产精品免费电影| 无码日韩精品一区二区免费| a毛片视频免费观看影院| 美女羞羞免费视频网站| 亚洲色精品三区二区一区| 亚洲视频在线免费观看| 亚洲免费人成在线视频观看| 免费v片在线观看无遮挡| 夫妻免费无码V看片| 四虎最新永久免费视频| 久久国产免费观看精品| 中文永久免费观看网站| 一区在线免费观看| 免费VA在线观看无码| 免费国产a理论片| 亚洲av最新在线观看网址| 亚洲va久久久久| 老司机69精品成免费视频| 一级白嫩美女毛片免费| 无套内谢孕妇毛片免费看看| 女bbbbxxxx另类亚洲| 精品亚洲国产成人av| 亚洲αⅴ无码乱码在线观看性色| 亚洲成a人片在线不卡| 亚洲卡一卡二卡乱码新区| 亚洲一级毛片免观看| 亚洲va久久久久| 亚洲熟妇AV日韩熟妇在线| 亚洲熟妇无码AV| 亚洲精华国产精华精华液好用| 亚洲欧好州第一的日产suv| 亚洲乱妇老熟女爽到高潮的片| 亚洲人成网站免费播放| 亚洲精品无码永久在线观看男男| 亚洲色偷偷综合亚洲AV伊人蜜桃 | 成人片黄网站色大片免费观看APP| 九一在线完整视频免费观看|