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

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

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

    love fish大鵬一曰同風起,扶搖直上九萬里

    常用鏈接

    統計

    積分與排名

    friends

    link

    最新評論

    JDK5.0中,對thread的一些改進(轉)

    1.創建線程
    在java中實現多線程有兩種方法,一個是直接繼承Thread類,一個是實現Runnable接口,但是推薦的是第二種。因為在邏輯上應該要把一個線程要做的事情以及做這個事情的方法分開;對于Thread來講,它只負責線程的操作,而具體要做的事情就應該放在Runnable中。但不管是那種方式,都要實現public void run()方法,但啟動線程用start而不是run。

    2.終止線程
    在1.0中,可以用stop方法來終止,但是現在這種方法已經被禁用了,改用interrupt方法。interrupt方法并不是強制終止線程,它只能設置線程的interrupted狀態,而在線程中一般使用一下方式:
    while (!Thread.currentThread().isInterrupted() && more work to do)
    {
    do more work
    }
    而被block的線程在被調用interrupt時會產生InterruptException,此時是否終止線程由本線程自己決定。程序的一般形式是:
    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方法也會產生InterruptedException,因此,如果每次在做完一些工作后調用了sleep方法,那么就不用檢查isInterrupted,而是直接捕捉InterruptedException。

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

    3.線程狀態
    New:當使用new創建一個線程時
    Runnable: 調用start或是從blocked狀態出來時
    Blocked:sleep, block on input/output, try to acquire lock, suspend, wait.
    Dead: 運行完成或有exception產生。

    4.線程優先級
    可以設置線程優先級,但是不能保證高優先級的線程就會被先運行

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

    6.為Uncaught Exceptions設置Handlers
    在java 5.0中,可以為線程中產生的unchecked exception設置一個處理器,這個處理器必須實現UncaughtExceptionHandler接口。
    可以調用線程實例的setUncaughtExceptionHandler方法為每個線程設置一個處理器,也可以調用Thread.setDefaultUncaughtExceptionHandler來為所有的線程設置一個默認的處理器。如果沒有給每一個線程設置處理器,那線程會首先使用線程組的處理器,如果還沒有再使用默認的處理器。

    7.Synchronization
    多線程很重要的一個問題就是同步的問題,如果不解決好同步的問題一個是可能會引起數據的混亂,而且還有可能造成線程的死鎖。在Java 5.0之前,用synchronized來解決這個問題,在5.0中加入了一個新的類: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
    }

    這個鎖被稱為Reentrant的原因是在一個線程中可以重復多次申請同一個鎖,系統會保留加鎖的次數,而在解鎖的時候也就必須執行相同次數。

    在一個線程已經得到鎖可以執行程序的時候,可能會發現需要的條件還不能滿足,這時他就必須等待直到條件滿足。但是因為它已經對所需要操作的東西加了鎖,其他的線程不能訪問,因此它又可能會永遠等待下去?,F在可以用Condition Object來避免這種情況。
    sufficientFunds = bankLock.newCondition();
    如果條件不滿足:
    sufficientFunds.await();
    這時線程就會釋放鎖并進入blocked狀態,其他線程就有機會執行操作。當其他線程執行完后,就可通知等待的線程繼續執行它的操作了:
    sufficientFunds.signalAll();
    當然也可以調用singal方法,這樣效率會高一些,但是有一定的危險性,因為它的喚醒具有隨機性。

    在5.0之前,采用的是synchronized關鍵字來進行同步,但是和lock相比它有一些局限性:
    1. 申請鎖的線程不能被interrupt
    2. 沒有timeout設置
    3. 只有一個隱性的condition條件

    另外,在申請鎖的時候可以用tryLock方法,它會返回一個bool值來表示鎖是否申請成功,如果沒有成功,程序就可以做其他的事情了。

    tryLock, await方法都可以被interrupt。

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

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

    FutureTask可以很方便的把Callable轉換成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創建線程池
    用線程池有兩個好處:1. 減少創建線程的開銷。2. 控制線程的數量。
    EXecutors提供了一些方法可以很方便的創建線程池:
    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時,先調用這些靜態方法創建線程池,得到一個ExecutorService對象,然后用這個對象的submit方法提交你的Runnable或是Callable對象。
    Future<?> submit(Runnable task)
    Future<T> submit(Runnable task, T result)
    Future<T> submit(Callable<T> task)
    如果不再需要任何提交,就用shutdown方法來關閉線程池。

    10.在界面中使用多線程
    對于GUI設計來說,很重要的一個原則就是要及時的給用戶反饋,就算是不能立即得到結果,界面也不能停在那里,是用戶不知道發生了什么事情,必須讓用戶隨時知道程序在坐什么。所以當程序要執行一段需要消耗比較長時間的操作時,就要使用多線程。

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

    如果想在自己另外所創建的線程執行過程中隨時更新界面來表示執行進程,要注意的一點是,這個線程并不能直接調用界面控件的方法,而要采用EventQueue類的invokeLater,invokeAndWait方法:
    EventQueue.invokeLater(new
    Runnable()
    {
    public void run()
    {
    label.setText(percentage + "% complete");
    }
    });

    posted on 2006-05-21 17:44 liaojiyong 閱讀(360) 評論(0)  編輯  收藏 所屬分類: Java

    主站蜘蛛池模板: 亚洲视频免费在线看| 亚洲一区二区三区无码中文字幕| 亚洲AV无码成人网站久久精品大| 国产精品免费久久久久久久久| 亚洲?V无码成人精品区日韩| 免费一区二区无码视频在线播放| 无码欧精品亚洲日韩一区夜夜嗨| 黄色毛片免费网站| 免费一级毛片一级毛片aa| 精品女同一区二区三区免费播放| 亚洲福利视频一区二区| 国产免费播放一区二区| 亚洲一区AV无码少妇电影☆| 成人电影在线免费观看| 久久久久亚洲av无码专区喷水| 中文字幕免费在线看线人| 亚洲精品一二三区| 日本免费一区二区三区最新vr| 男男gay做爽爽免费视频| 亚洲人成亚洲人成在线观看 | 337p日本欧洲亚洲大胆精品555588| 99在线热视频只有精品免费| 亚洲综合久久1区2区3区| 成人免费无码大片A毛片抽搐色欲| 女bbbbxxxx另类亚洲| 亚洲色婷婷综合开心网| 免费人妻无码不卡中文字幕系| 亚洲人成免费电影| 亚洲 综合 国产 欧洲 丝袜| 青青青国产手机频在线免费观看| 亚洲网站在线播放| 国产精品另类激情久久久免费| 两个人看的www免费高清| 亚洲av一本岛在线播放| 亚洲一区二区三区国产精品| www视频在线观看免费| 免费人成大片在线观看播放电影| 亚洲va久久久噜噜噜久久狠狠| 免费无码又黄又爽又刺激| 国产福利电影一区二区三区,免费久久久久久久精 | 国产成人综合久久精品免费|