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

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

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

    FORTUNE

    THE WAY TO THE MASTER...
    posts - 49, comments - 18, trackbacks - 0, articles - 1
      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    java線(xiàn)程

    Posted on 2006-04-12 09:41 fortune 閱讀(1169) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): java技術(shù)
    在新的JDK5.0中,對(duì)thread做了一些改進(jìn),我通過(guò)閱讀一些資料寫(xiě)下了下面的總結(jié),請(qǐng)大家看看。

    1.創(chuàng)建線(xiàn)程
    在java中實(shí)現(xiàn)多線(xiàn)程有兩種方法,一個(gè)是直接繼承Thread類(lèi),一個(gè)是實(shí)現(xiàn)Runnable接口,但是推薦的是第二種。因?yàn)樵谶壿嬌蠎?yīng)該要把一個(gè)線(xiàn)程要做的事情以及做這個(gè)事情的方法分開(kāi);對(duì)于Thread來(lái)講,它只負(fù)責(zé)線(xiàn)程的操作,而具體要做的事情就應(yīng)該放在Runnable中。但不管是那種方式,都要實(shí)現(xiàn)public void run()方法,但啟動(dòng)線(xiàn)程用start而不是run。

    2.終止線(xiàn)程
    在1.0中,可以用stop方法來(lái)終止,但是現(xiàn)在這種方法已經(jīng)被禁用了,改用interrupt方法。interrupt方法并不是強(qiáng)制終止線(xiàn)程,它只能設(shè)置線(xiàn)程的interrupted狀態(tài),而在線(xiàn)程中一般使用一下方式:
    while (!Thread.currentThread().isInterrupted() && more work to do)
    {
    do more work
    }
    而被block的線(xiàn)程在被調(diào)用interrupt時(shí)會(huì)產(chǎn)生InterruptException,此時(shí)是否終止線(xiàn)程由本線(xiàn)程自己決定。程序的一般形式是:
    public void run()
    {
    try
    {
    . . .
    while (!Thread.currentThread().isInterrupted() && more work to do)
    {
    do more work
    }
    }
    catch(InterruptedException e)
    {
    // thread was interrupted during sleep or wait
    }
    finally
    {
    cleanup, if required
    }
    // exiting the run method terminates the thread
    }

    Thread.sleep方法也會(huì)產(chǎn)生InterruptedException,因此,如果每次在做完一些工作后調(diào)用了sleep方法,那么就不用檢查isInterrupted,而是直接捕捉InterruptedException。

    在捕捉到InterruptedException時(shí),如果沒(méi)有其他的事情可做,最好做一下處理,不能用{}
    1)
    void mySubTask()
    {
    . . .
    try { sleep(delay); }
    catch (InterruptedException e) { Thread().currentThread().interrupt(); }
    . . .
    }
    或是
    2)
    void mySubTask() throws InterruptedException
    {
    . . .
    sleep(delay);
    . . .
    }

    3.線(xiàn)程狀態(tài)
    New:當(dāng)使用new創(chuàng)建一個(gè)線(xiàn)程時(shí)
    Runnable: 調(diào)用start或是從blocked狀態(tài)出來(lái)時(shí)
    Blocked:sleep, block on input/output, try to acquire lock, suspend, wait.
    Dead: 運(yùn)行完成或有exception產(chǎn)生。

    4.線(xiàn)程優(yōu)先級(jí)
    可以設(shè)置線(xiàn)程優(yōu)先級(jí),但是不能保證高優(yōu)先級(jí)的線(xiàn)程就會(huì)被先運(yùn)行

    5.線(xiàn)程組
    可以把多個(gè)線(xiàn)程加到一個(gè)線(xiàn)程組里面去,這樣可以對(duì)這些線(xiàn)程進(jìn)行一些統(tǒng)一的操作,例如
    ThreadGroup g = new ThreadGroup(groupName)
    ...
    g.interrupt(); // interrupt all threads in group g

    6.為Uncaught Exceptions設(shè)置Handlers
    在java 5.0中,可以為線(xiàn)程中產(chǎn)生的unchecked exception設(shè)置一個(gè)處理器,這個(gè)處理器必須實(shí)現(xiàn)UncaughtExceptionHandler接口。
    可以調(diào)用線(xiàn)程實(shí)例的setUncaughtExceptionHandler方法為每個(gè)線(xiàn)程設(shè)置一個(gè)處理器,也可以調(diào)用Thread.setDefaultUncaughtExceptionHandler來(lái)為所有的線(xiàn)程設(shè)置一個(gè)默認(rèn)的處理器。如果沒(méi)有給每一個(gè)線(xiàn)程設(shè)置處理器,那線(xiàn)程會(huì)首先使用線(xiàn)程組的處理器,如果還沒(méi)有再使用默認(rèn)的處理器。

    7.Synchronization
    多線(xiàn)程很重要的一個(gè)問(wèn)題就是同步的問(wèn)題,如果不解決好同步的問(wèn)題一個(gè)是可能會(huì)引起數(shù)據(jù)的混亂,而且還有可能造成線(xiàn)程的死鎖。在Java 5.0之前,用synchronized來(lái)解決這個(gè)問(wèn)題,在5.0中加入了一個(gè)新的類(lèi):ReentrantLock

    使用lock的基本形式是:
    myLock.lock(); // a ReentrantLock object
    try
    {
    critical section
    }
    finally
    {
    myLock.unlock(); // make sure the lock is unlocked even if an exception is thrown
    }

    這個(gè)鎖被稱(chēng)為Reentrant的原因是在一個(gè)線(xiàn)程中可以重復(fù)多次申請(qǐng)同一個(gè)鎖,系統(tǒng)會(huì)保留加鎖的次數(shù),而在解鎖的時(shí)候也就必須執(zhí)行相同次數(shù)。

    在一個(gè)線(xiàn)程已經(jīng)得到鎖可以執(zhí)行程序的時(shí)候,可能會(huì)發(fā)現(xiàn)需要的條件還不能滿(mǎn)足,這時(shí)他就必須等待直到條件滿(mǎn)足。但是因?yàn)樗呀?jīng)對(duì)所需要操作的東西加了鎖,其他的線(xiàn)程不能訪問(wèn),因此它又可能會(huì)永遠(yuǎn)等待下去?,F(xiàn)在可以用Condition Object來(lái)避免這種情況。
    sufficientFunds = bankLock.newCondition();
    如果條件不滿(mǎn)足:
    sufficientFunds.await();
    這時(shí)線(xiàn)程就會(huì)釋放鎖并進(jìn)入blocked狀態(tài),其他線(xiàn)程就有機(jī)會(huì)執(zhí)行操作。當(dāng)其他線(xiàn)程執(zhí)行完后,就可通知等待的線(xiàn)程繼續(xù)執(zhí)行它的操作了:
    sufficientFunds.signalAll();
    當(dāng)然也可以調(diào)用singal方法,這樣效率會(huì)高一些,但是有一定的危險(xiǎn)性,因?yàn)樗膯拘丫哂须S機(jī)性。

    在5.0之前,采用的是synchronized關(guān)鍵字來(lái)進(jìn)行同步,但是和lock相比它有一些局限性:
    1. 申請(qǐng)鎖的線(xiàn)程不能被interrupt
    2. 沒(méi)有timeout設(shè)置
    3. 只有一個(gè)隱性的condition條件

    另外,在申請(qǐng)鎖的時(shí)候可以用tryLock方法,它會(huì)返回一個(gè)bool值來(lái)表示鎖是否申請(qǐng)成功,如果沒(méi)有成功,程序就可以做其他的事情了。

    tryLock, await方法都可以被interrupt。

    java.util.concurrent.locks包中提供了兩種鎖,一個(gè)就是ReentrantLock,另一個(gè)是ReentrantReadWriteLock,一般用于多操作遠(yuǎn)遠(yuǎn)多于寫(xiě)操作的時(shí)候:
    private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    private Lock readLock = rwl.readLock();
    private Lock writeLock = rwl.writeLock();

    8. Callables and Futures
    實(shí)現(xiàn)多線(xiàn)程時(shí)一般用的是Runnable接口,但是他有一個(gè)問(wèn)題就是他沒(méi)有參數(shù)和返回值,所以當(dāng)執(zhí)行一個(gè)線(xiàn)程需要返回一個(gè)值的時(shí)候就不是很方便了。Callable接口和Runnable差不多,但是他提供了參數(shù)和返回值:
    public interface Callable<V>
    {
    V call() throws Exception;
    }
    而Future接口可以保留異步執(zhí)行的值:
    public interface Future<V>
    {
    V get() throws . . .;
    V get(long timeout, TimeUnit unit) throws . . .;
    void cancel(boolean mayInterrupt);
    boolean isCancelled();
    boolean isDone();
    }

    FutureTask可以很方便的把Callable轉(zhuǎn)換成Future和Runnable:
    Callable<Integer> myComputation = . . .;
    FutureTask<Integer> task = new FutureTask<Integer>(myComputation);
    Thread t = new Thread(task); // it's a Runnable
    t.start();
    . . .
    Integer result = task.get(); // it's a Future

    9.用Executors創(chuàng)建線(xiàn)程池
    用線(xiàn)程池有兩個(gè)好處:1. 減少創(chuàng)建線(xiàn)程的開(kāi)銷(xiāo)。2. 控制線(xiàn)程的數(shù)量。
    EXecutors提供了一些方法可以很方便的創(chuàng)建線(xiàn)程池:
    newCachedThreadPool
    New threads are created as needed; idle threads are kept for 60 seconds.

    newFixedThreadPool
    The pool contains a fixed set of threads; idle threads are kept indefinitely.

    newSingleThreadExecutor
    A "pool" with a single thread that executes the submitted tasks sequentially.

    newScheduledThreadPool
    A fixed-thread pool for scheduled execution.

    newSingleThreadScheduledExecutor
    A single-thread "pool" for scheduled execution.

    在使用Executors時(shí),先調(diào)用這些靜態(tài)方法創(chuàng)建線(xiàn)程池,得到一個(gè)ExecutorService對(duì)象,然后用這個(gè)對(duì)象的submit方法提交你的Runnable或是Callable對(duì)象。
    Future<?> submit(Runnable task)
    Future<T> submit(Runnable task, T result)
    Future<T> submit(Callable<T> task)
    如果不再需要任何提交,就用shutdown方法來(lái)關(guān)閉線(xiàn)程池。

    10.在界面中使用多線(xiàn)程
    對(duì)于GUI設(shè)計(jì)來(lái)說(shuō),很重要的一個(gè)原則就是要及時(shí)的給用戶(hù)反饋,就算是不能立即得到結(jié)果,界面也不能停在那里,是用戶(hù)不知道發(fā)生了什么事情,必須讓用戶(hù)隨時(shí)知道程序在坐什么。所以當(dāng)程序要執(zhí)行一段需要消耗比較長(zhǎng)時(shí)間的操作時(shí),就要使用多線(xiàn)程。

    但是,有些界面控件并不是線(xiàn)程安全的,在使用這些控件時(shí)就要特別注意。在API doc中這些都有注明,使用的時(shí)候就可以查一下。

    如果想在自己另外所創(chuàng)建的線(xiàn)程執(zhí)行過(guò)程中隨時(shí)更新界面來(lái)表示執(zhí)行進(jìn)程,要注意的一點(diǎn)是,這個(gè)線(xiàn)程并不能直接調(diào)用界面控件的方法,而要采用EventQueue類(lèi)的invokeLater,invokeAndWait方法:
    EventQueue.invokeLater(new
    Runnable()
    {
    public void run()
    {
    label.setText(percentage + "% complete");
    }
    });

    主站蜘蛛池模板: 久久水蜜桃亚洲AV无码精品 | 日韩免费视频一区| 成全在线观看免费观看大全 | 国产91免费视频| 国产中文字幕在线免费观看| 国产精品亚洲自在线播放页码| 国产亚洲真人做受在线观看| 日韩成人免费aa在线看| 午夜免费1000部| 久久青草免费91观看| 一区二区三区AV高清免费波多| 亚洲中文无码亚洲人成影院| 337p日本欧洲亚洲大胆色噜噜| 亚洲一区二区三区国产精品| 精品国产一区二区三区免费看| 精品无码免费专区毛片| 日本在线免费播放| 中国黄色免费网站| 九九久久国产精品免费热6| 亚洲高清乱码午夜电影网| 亚洲冬月枫中文字幕在线看| 99人中文字幕亚洲区| 亚洲AV日韩精品久久久久| 亚洲乳大丰满中文字幕| 亚洲人成网站色在线入口| 国产又粗又长又硬免费视频| 免费观看的毛片手机视频| 成年在线网站免费观看无广告 | 日韩一品在线播放视频一品免费| 国产h视频在线观看网站免费| 日韩人妻一区二区三区免费| 最近免费中文字幕中文高清 | 免费看一级做a爰片久久| 成人毛片免费观看视频在线| 中文字幕无码不卡免费视频| 2020久久精品国产免费| 亚洲人成免费网站| 日韩不卡免费视频| 最近中文字幕免费mv视频8| 最近免费中文字幕视频高清在线看| 24小时免费直播在线观看|