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

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

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

    隨筆-204  評論-149  文章-0  trackbacks-0
    在學校的論壇Java版發現很多問關于這樣的問題,比如這幾個方法有什么區別,想看t.interrupt()方法后線程的中斷狀態;如何終止一個線程
    其實之前已經大部分提及到?,F總結一下,然后加上例子,畢竟例子容易理解
    http://m.tkk7.com/fhtdy2004/archive/2009/06/08/280728.html中有關interrupt()的解釋已經很清楚了

    interrupt

    public void interrupt()
    中斷線程。

    如果當前線程沒有中斷它自己(這在任何情況下都是允許的),則該線程的 checkAccess 方法就會被調用,這可能拋出 SecurityException。

    如果線程在調用 Object 類的 wait()、wait(long)wait(long, int) 方法,或者該類的 join()、join(long)、join(long, int)sleep(long)sleep(long, int) 方法過程中受阻,則其中斷狀態將被清除,它還將收到一個 InterruptedException。

    如果該線程在可中斷的通道上的 I/O 操作中受阻,則該通道將被關閉,該線程的中斷狀態將被設置并且該線程將收到一個 ClosedByInterruptException。

    如果該線程在一個 Selector 中受阻,則該線程的中斷狀態將被設置,它將立即從選擇操作返回,并可能帶有一個非零值,就好像調用了選擇器的 wakeup 方法一樣。

    如果以前的條件都沒有保存,則該線程的中斷狀態將被設置。

     

    拋出:
    SecurityException - 如果當前線程無法修改該線程

    interrupted

    public static boolean interrupted()
    測試當前線程是否已經中斷。線程的中斷狀態 由該方法清除。換句話說,如果連續兩次調用該方法,則第二次調用將返回 false(在第一次調用已清除了其中斷狀態之后,且第二次調用檢驗完中斷狀態前,當前線程再次中斷的情況除外)。

     

    返回:
    如果當前線程已經中斷,則返回 true;否則返回 false。
    另請參見:
    isInterrupted()

    isInterrupted

    public boolean isInterrupted()
    測試線程是否已經中斷。線程的中斷狀態 不受該方法的影響。

     

    返回:
    如果該線程已經中斷,則返回 true;否則返回 false。
    另請參見:
    interrupted()

    t.interrupt()不會中斷正在執行的線程,只是將線程的標志位設置成true。但是如果線程在調用sleep(),join(),wait()方法時線程被中斷,則這些方法會拋出InterruptedException,在catch塊中捕獲到這個異常時,線程的中斷標志位已經被設置成false了,因此在此catch塊中調用t.isInterrupted(),Thread.interrupted()始終都為false,
    而t.isInterrupted與Thread.interrupted()的區別是API中已經說明很明顯了,Thread.interrupted()假如當前的中斷標志為true,則調完后會將中斷標志位設置成false
    package threadtest;

    import java.util.Timer;
    import java.util.TimerTask;

    class CanStop extends Thread {

        
    private int counter = 0;

        
    public void run() {
            
    boolean done = false;
            
    try{
                Thread.sleep(
    100);//設置成100比主線程中的500要小
            }
    catch(InterruptedException ie){
                ie.printStackTrace();
                
    //return;假如要使用interrupt來終止線程則在捕獲的InterruptedException中return
            }

            
    while (counter < 100000 &&!done) {
                System.out.println(counter
    ++);
                
    //在主線程中調用stoppable.interrupt()之前為false,假如之后沒有調用Thread.interrupted()則一直為true,
                
    //否則為第一次為true,調用Thread.interrupted之后為false
                System.out.println("in thread stoppable.isInterrupted() "+isInterrupted());
                
                
    //System.out.println("stoppable.isInterrupted() "+Thread.interrupted());////在主線程中調用stoppable.interrupt()之前為false,之后只有第一個會顯示為true,之后全為false
                
                
    //調用Thread.interrupted()一次會清除線程的中斷標志位,因此以后都為false
                if(Thread.interrupted()==true){
                    
    try{
                        
    //Thread.interrupted()會清除中斷標志位,顯然這里面只會調用一次
                        System.out.println("in thread after Thread.interrupted() "+isInterrupted());
                        sleep(
    10000);
                    }
    catch(InterruptedException ie){
                        ie.printStackTrace();
                        
                    }

                }

            }

        }

        
    }


    public class CheckInterrupt {
        
    public static void main(String[] args) {
            
    final CanStop stoppable = new CanStop();
            stoppable.start();
            
    new Timer(true).schedule(new TimerTask() {
                
    public void run() {
                    System.out.println(
    "Requesting Interrupt");
                    stoppable.interrupt();
    //不會中斷正在執行的線程,原因是因為interrupt()方法只設置中斷狀態標志位為true
                    System.out.println("in timer stoppable.isInterrupted() "+stoppable.isInterrupted());
                }

            }
    500); // run() after 500 milliseconds
        }

    }



    2,關于interrupte()打斷sleep()
    package threadtest;

    //Understanding join().

    class Sleeper extends Thread {
        
    private int duration;

        
    public Sleeper(String name, int sleepTime) {
            
    super(name);
            duration 
    = sleepTime;
            start();
        }


        
    public void run() {
            
    try {
                sleep(duration);
            }
     catch (InterruptedException e) {
                
    // System.out.println(getName() + " was interrupted. " +
                
    // "isInterrupted(): " + isInterrupted());
                System.out.println(getName() + " in catch Thread.interrupted(). "
                        
    + "Thread.interrupted(): " + Thread.interrupted());
                
    return;
            }

            System.out.println(getName() 
    + " has awakened");
        }

    }


    class Joiner extends Thread {
        
    private Sleeper sleeper;

        
    public Joiner(String name, Sleeper sleeper) {
            
    super(name);
            
    this.sleeper = sleeper;
            start();
        }


        
    public void run() {
            
    try {
                sleeper.join();
            }
     catch (InterruptedException e) {
                
    //run方法不能Throw CheckedException,要拋只能拋出RuntimeException,也不會被主線程捕獲
                //要使主線程能夠捕獲這個RuntimeException請參見另外一篇文章
                //地址:http://m.tkk7.com/fhtdy2004/archive/2009/08/07/290210.html

                throw new RuntimeException(e);
            }

            System.out.println(getName() 
    + " join completed");
        }

    }


    public class Joining {

        
    public static void main(String[] args) {
            Sleeper sleepy 
    = new Sleeper("Sleepy"1500),
                    grumpy 
    = new Sleeper("Grumpy"1500);
            Joiner  dopey 
    = new Joiner("Dopey", sleepy), 
                    doc 
    = new Joiner("Doc",grumpy);
            
    grumpy.interrupt();
            //doc.interrupt();

        }

    }

    Sleeper是一個會睡上一段時間的Thread,至于睡多長時間,這要由構造函數的參數決定。Sleeperrun( )sleep( )可以因時限到期而返回,也可以被interrupt( )打斷。catch語句在報告中斷的同時,會一并報告isInterrupted( )。當有別的線程調用了本線程的interrupt( )時,會設置一個標記以表示這個這個線程被打斷了。當本線程捕獲這個異常的時候,會清除這個標志。所以catch語句會永遠報告說isInterrupted( )是false。這個標記是用來應付其它情況的,或許在沒出異常的情況下,線程要用它來檢查自己是不是被中斷了。
    Joiner是另一個線程,它調用了Sleeperjoin( ),所以它要等Sleeper醒過來。main( )創建了兩個Sleeper分派給兩個Joiner。你會發現,不論Sleeper是被打斷還是正常結束,Joiner都會隨Sleeper一道結束。





    2,如何終止一個線程:
    package test.thread.one;

    import java.util.Timer;
    import java.util.TimerTask;

    class CanStop extends Thread {
        
    // Must be volatile:
        private volatile boolean stop = false;

        
    private int counter = 0;

        
    public void run() {
            
    while (!stop && counter < 100000{
                System.out.println(counter
    ++);
            }

            
    if (stop)
                System.out.println(
    "Detected stop");
        }


        
    public void requestStop() {
            stop 
    = true;
        }

    }


    public class Stopping {
        
    public static void main(String[] args) {
            
    final CanStop stoppable = new CanStop();
            stoppable.start();
            
    new Timer(true).schedule(new TimerTask() {
                
    public void run() {
                    System.out.println(
    "Requesting stop");
                    stoppable.requestStop();
                }

            }
    500); // run() after 500 milliseconds
        }

    }

    stop必須是volatile的,這樣才能確保run( )方法能看到它(否則它會使用本地的緩存值)。這個線程的"任務"是打印10,000個數字,所以當counter >= 10000或有人要它停下來的時候,它就結束了。注意requestStop( )不是synchronized,因為stop既是boolean(改成true是一個原子操作)又是volatile的。

    或者
    package test.thread.three;

    import java.util.Timer;
    import java.util.TimerTask;

    class CanStop extends Thread {
        
        
    private boolean stop = false;

        
    private int counter = 0;

        
    public void run() {
            
    boolean done = false;
            
    try{
                Thread.sleep(
    100);
            }
    catch(InterruptedException ie){
                ie.printStackTrace();
                
    //return;假如要使用interrupt來終止線程則在捕獲的InterruptedException中return
            }

            
    while (!getStopRequest() && counter < 100000 &&!done) {
                System.out.println(counter
    ++);
            }

            
    if (getStopRequest())
                System.out.println(
    "Detected stop");
        }

        
        
        
    public synchronized boolean getStopRequest(){
            
    return stop;
        }


        
    public synchronized void requestStop() {
            stop 
    = true;
        }

    }


    public class Stopping {
        
    public static void main(String[] args) {
            
    final CanStop stoppable = new CanStop();
            stoppable.start();
            
    new Timer(true).schedule(new TimerTask() {
                
    public void run() {
                    System.out.println(
    "Requesting stop");
                    stoppable.requestStop();
                }

            }
    500); // run() after 500 milliseconds
        }

    }


    打斷受阻的線程
    有時線程受阻之后就不能再做輪詢了,比如在等輸入,這時你就不能像前面那樣去查詢旗標了。碰到這種情況,你可以用Thread.interrupt( )方法打斷受阻的線程:

    //: c13:Interrupt.java
    // Using interrupt() to break out of a blocked thread.
    import java.util.*;
    class Blocked extends Thread {
      
    public Blocked() {
        System.out.println(
    "Starting Blocked");
        start();
      }

      
    public void run() {
        
    try {
          
    synchronized(this{
            wait(); 
    // Blocks
          }

        }
     catch(InterruptedException e) {
          System.out.println(
    "Interrupted");
        }

        System.out.println(
    "Exiting run()");
      }

    }

    public class Interrupt {
      
    static Blocked blocked = new Blocked();
      
    public static void main(String[] args) {
        
    new Timer(true).schedule(new TimerTask() {
          
    public void run() {
            System.out.println(
    "Preparing to interrupt");
            blocked.interrupt();
            blocked 
    = null// to release it
          }

        }
    2000); // run() after 2000 milliseconds
      }

    }
     ///


    3.避免過多的同步,永遠不要在循環外面調用wait

    為了避免死鎖的危險,在一個被同步的的方法或者代碼快中,永遠不要放棄對客戶的限制。
    換句話說,在一個被同步的區域內部,不要調用一個可被改寫的公有或受保護的方法(這樣的方法往往是一個抽象方法,但偶爾他們也會有一個默認的實現,)從包含該同步區域的類的角度來看,這樣的方法是一個外來者alien。這個類不知道該類會做什么事情,也控制不力它。客戶可以為這個外來方法提供一個實現,并且在該方法中創建了一個線程,再回調到這個類中。然后,新建的線程試圖獲取原線程所擁有的那把鎖,這樣會導致新建的線程被阻塞。如果創建該線程的方法在等待這個線程完成這個任務,則死鎖就形成了。


    Object.wait方法的作用是使一個線程等待某個條件。它一定是在一個同步區域中被調用,而且該同步區域鎖住了被調用的對象。下面是wait方法的標準模式:
    synchronized(obj){
          while(<condition does not hold>)
                obj.wait();
          ...//perform action appropriate to condition
    }
    總是使用wait循環模式來調用wait方法。而不是if來調用。永遠不要在循環的外面調用wait。循環被用于等待的前后測試條件

    package effective.java;

    import java.io.BufferedInputStream;
    import java.util.LinkedList;
    import java.util.List;

    public abstract class WorkQueue {
        
        
    private final List queue = new LinkedList();
        
        
    private boolean stopped = false;
        
        StringBuffer sb;
        BufferedInputStream bis;
        
        
    protected WorkQueue(){
            
    new WorkerThread2().start();
        }

        
        
    public final void enqueue(Object workItem){
            
    synchronized(queue){
                queue.add(workItem);
                queue.notify();
            }

        }

        
        
    public final void stop(){
            
    synchronized(queue){
                stopped 
    = true;
                queue.notify();
            }

        }

        
        
    protected abstract void processItem(Object workItem)throws InterruptedException;
        
        
    //Broken - invokes alien method from synchronized block
        private class WorkerThread extends Thread{
            
    public void run(){
                
    while(true){
                    
    synchronized(WorkQueue.this.queue){
                        
    try{
                            
    while(queue.isEmpty() && !stopped){
                                queue.wait();
                            }

                        }
    catch(InterruptedException ie){
                            ie.printStackTrace();
                            
    return;
                        }

                        
                        
    if(stopped)
                            
    return;
                        Object workItem 
    = queue.remove(0);
                        
    try{
                            processItem(workItem);
    //lock held
                        }
    catch(InterruptedException ie){
                            System.out.println(
    "ddd"+ie);
                            
    return;
                        }

                    }

                }

            }

        }

        
        
        
    //Alien method outside synchronized block -"open call"
        private class WorkerThread2 extends Thread{
            
    public void run(){
                
    while(true){
                    Object workItem 
    = null;
                    
    synchronized(WorkQueue.this.queue){
                        
    try{
                            
    while(queue.isEmpty() && !stopped){
                                queue.wait();
                            }

                        }
    catch(InterruptedException ie){
                            
    return;
                        }

                        
                        
    if(stopped)
                            
    return;
                        workItem 
    = queue.remove(0);    
                    }

                    
                    
    try{
                        processItem(workItem);
    //No lock held
                    }
    catch(InterruptedException ie){
                        
    return;
                    }

                }

            }

        }

    }


    package effective.java;

    public class DisplayQueue extends WorkQueue {

        @Override
        
    protected void processItem(Object workItem) throws InterruptedException {
            System.out.println(workItem);
            System.out.println(
    "模擬此線程做耗時工作");
            Thread.sleep(
    1000);
        }

        
        
    public static void main(String[] args){
            WorkQueue wq 
    = new DisplayQueue();
            
    for(int i=0;i<10;i++){
                String s 
    = new String("object_"+i);
                System.out.println(
    "main thread add " + s+" to queue");
                wq.enqueue(s);
                
    try{
                    Thread.sleep(
    500);
                }
    catch(InterruptedException ie){
                    ie.printStackTrace();
                }

            }

            
    //wq.stop();
        }


    }




    class DeadLockQueue extends WorkQueue{

        @Override
        
    protected void processItem(final Object workItem) throws InterruptedException {
            
            Thread child 
    = new Thread(){
                
    public void run(){
                    
    //DeadLockQueue.this.enqueue(workItem);
                    System.out.println("在將對象入隊列 "+workItem);
                    enqueue(workItem);
                }

            }
    ;
            child.start();
            child.join();
    //dead lock
            
        }

        
        
    }



    4.保持可運行線程數量盡可能的少的主要技術是,讓每個線程做少量的工作,然后使用Object.wait等待某個條件發生,或者使用Thread.sleep()睡眠一段時間,線程不應該忙-等busy-wait,即反復的檢查一個數據結構,以等待某些事件發生。除了使程序易受調度器的變化的影響外,忙等這種做法還會增加處理器的負擔
    busy-wait
    package effective.java;

    import java.util.LinkedList;
    import java.util.List;

    public abstract class WorkQueueBusyWait {
        
        
    private final List queue = new LinkedList();
        
        
    private boolean stopped = false;
        
        
    protected WorkQueueBusyWait(){
            
    new WorkThread().start();
        }

        
        
    public final void enqueue(Object workItem){
            
    synchronized(queue){
                queue.add(workItem);
            }

        }

        
        
    public final void stop(){
            
    synchronized(queue){
                stopped 
    = true;
            }

        }

        
        
    protected abstract void processItem(Object workitem) throws InterruptedException;
        
        
    private class WorkThread extends Thread{
            
    public void run(){
                
    final Object QUEUE_IS_EMPTY = new Object();
                
    while(true){
                    Object workItem 
    = QUEUE_IS_EMPTY;
                    
    synchronized(queue){
                        
    if(stopped)
                            
    return;
                        
    if(!queue.isEmpty())
                            workItem  
    = queue.remove(0);
                    }

                    
    if(workItem != QUEUE_IS_EMPTY){
                        
    try{
                            processItem(workItem);
                        }
    catch(InterruptedException ie){
                            ie.printStackTrace();
                            
    return;
                        }

                    }

                }

            }

        }

    }


    class PingPongQueue extends WorkQueue{
        
    volatile int count=0;
        @Override
        
    protected void processItem(final Object workItem) throws InterruptedException {
            count
    ++;
            WorkQueue recipient 
    = (WorkQueue)workItem;
            recipient.enqueue(
    this);
        }

        
    }


    package effective.java;

    public class WaitQueuePerf {

        
    /**
         * 
    @param args
         
    */

        
    public static void main(String[] args) {
            
            PingPongQueue q1 
    = new PingPongQueue();
            PingPongQueue q2 
    = new PingPongQueue();
            q1.enqueue(q2);
            
            
    try{
                Thread.sleep(
    1000);
            }
    catch(InterruptedException ie){
                ie.printStackTrace();
            }

            
            
    int count = q1.count;
            
    try{
                Thread.sleep(
    1000);
            }
    catch(InterruptedException ie){
                ie.printStackTrace();
            }

            System.out.println(q1.count
    -count);
            q1.stop();
            q2.stop();

        }


    }


    posted on 2009-08-22 11:07 Frank_Fang 閱讀(4830) 評論(0)  編輯  收藏 所屬分類: Java編程
    主站蜘蛛池模板: 成人国产网站v片免费观看| 亚洲妇女无套内射精| 亚洲偷自精品三十六区| 亚洲色在线无码国产精品不卡| 欧美亚洲精品一区二区| a级毛片免费高清视频| 日韩免费电影网站| 扒开双腿猛进入爽爽免费视频 | 一级毛片免费毛片一级毛片免费| 67194国产精品免费观看| 性一交一乱一视频免费看| 亚洲精品视频免费| 亚洲综合久久综合激情久久| 午夜在线a亚洲v天堂网2019| 成人a毛片视频免费看| h片在线免费观看| 亚洲av无码乱码在线观看野外| 国产l精品国产亚洲区在线观看| 亚洲av乱码一区二区三区 | 亚洲GV天堂无码男同在线观看| 国产精品免费久久| 日本亚洲免费无线码| 亚洲精品国产精品乱码不卡| 久久精品国产亚洲av高清漫画| 国产精品亚洲а∨无码播放麻豆| 久久免费高清视频| 国产精品四虎在线观看免费| 久久精品国产亚洲av四虎| 亚洲国产精品无码久久久秋霞1| 成人av片无码免费天天看| 成年性午夜免费视频网站不卡| 亚洲香蕉成人AV网站在线观看| 亚洲一级毛片视频| 中国一级毛片视频免费看| 无码少妇一区二区浪潮免费| 色噜噜亚洲精品中文字幕| 亚洲kkk4444在线观看| 免费a级毛片无码a∨免费软件 | 高清国语自产拍免费视频国产 | 亚洲国产日韩成人综合天堂| 亚洲国产精品乱码在线观看97|