<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
    在學(xué)校的論壇Java版發(fā)現(xiàn)很多問關(guān)于這樣的問題,比如這幾個方法有什么區(qū)別,想看t.interrupt()方法后線程的中斷狀態(tài);如何終止一個線程
    其實之前已經(jīng)大部分提及到。現(xiàn)總結(jié)一下,然后加上例子,畢竟例子容易理解
    http://www.tkk7.com/fhtdy2004/archive/2009/06/08/280728.html中有關(guān)interrupt()的解釋已經(jīng)很清楚了

    interrupt

    public void interrupt()
    中斷線程。

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

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

    如果該線程在可中斷的通道上的 I/O 操作中受阻,則該通道將被關(guān)閉,該線程的中斷狀態(tài)將被設(shè)置并且該線程將收到一個 ClosedByInterruptException

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

    如果以前的條件都沒有保存,則該線程的中斷狀態(tài)將被設(shè)置。

     

    拋出:
    SecurityException - 如果當(dāng)前線程無法修改該線程

    interrupted

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

     

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

    isInterrupted

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

     

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

    t.interrupt()不會中斷正在執(zhí)行的線程,只是將線程的標(biāo)志位設(shè)置成true。但是如果線程在調(diào)用sleep(),join(),wait()方法時線程被中斷,則這些方法會拋出InterruptedException,在catch塊中捕獲到這個異常時,線程的中斷標(biāo)志位已經(jīng)被設(shè)置成false了,因此在此catch塊中調(diào)用t.isInterrupted(),Thread.interrupted()始終都為false,
    而t.isInterrupted與Thread.interrupted()的區(qū)別是API中已經(jīng)說明很明顯了,Thread.interrupted()假如當(dāng)前的中斷標(biāo)志為true,則調(diào)完后會將中斷標(biāo)志位設(shè)置成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);//設(shè)置成100比主線程中的500要小
            }
    catch(InterruptedException ie){
                ie.printStackTrace();
                
    //return;假如要使用interrupt來終止線程則在捕獲的InterruptedException中return
            }

            
    while (counter < 100000 &&!done) {
                System.out.println(counter
    ++);
                
    //在主線程中調(diào)用stoppable.interrupt()之前為false,假如之后沒有調(diào)用Thread.interrupted()則一直為true,
                
    //否則為第一次為true,調(diào)用Thread.interrupted之后為false
                System.out.println("in thread stoppable.isInterrupted() "+isInterrupted());
                
                
    //System.out.println("stoppable.isInterrupted() "+Thread.interrupted());////在主線程中調(diào)用stoppable.interrupt()之前為false,之后只有第一個會顯示為true,之后全為false
                
                
    //調(diào)用Thread.interrupted()一次會清除線程的中斷標(biāo)志位,因此以后都為false
                if(Thread.interrupted()==true){
                    
    try{
                        
    //Thread.interrupted()會清除中斷標(biāo)志位,顯然這里面只會調(diào)用一次
                        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();
    //不會中斷正在執(zhí)行的線程,原因是因為interrupt()方法只設(shè)置中斷狀態(tài)標(biāo)志位為true
                    System.out.println("in timer stoppable.isInterrupted() "+stoppable.isInterrupted());
                }

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

    }



    2,關(guān)于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://www.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,至于睡多長時間,這要由構(gòu)造函數(shù)的參數(shù)決定。Sleeperrun( )sleep( )可以因時限到期而返回,也可以被interrupt( )打斷。catch語句在報告中斷的同時,會一并報告isInterrupted( )當(dāng)有別的線程調(diào)用了本線程的interrupt( )時,會設(shè)置一個標(biāo)記以表示這個這個線程被打斷了。當(dāng)本線程捕獲這個異常的時候,會清除這個標(biāo)志。所以catch語句會永遠(yuǎn)報告說isInterrupted( )是false。這個標(biāo)記是用來應(yīng)付其它情況的,或許在沒出異常的情況下,線程要用它來檢查自己是不是被中斷了。
    Joiner是另一個線程,它調(diào)用了Sleeperjoin( ),所以它要等Sleeper醒過來。main( )創(chuàng)建了兩個Sleeper分派給兩個Joiner。你會發(fā)現(xiàn),不論Sleeper是被打斷還是正常結(jié)束,Joiner都會隨Sleeper一道結(jié)束。





    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( )方法能看到它(否則它會使用本地的緩存值)。這個線程的"任務(wù)"是打印10,000個數(shù)字,所以當(dāng)counter >= 10000或有人要它停下來的時候,它就結(jié)束了。注意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
        }

    }


    打斷受阻的線程
    有時線程受阻之后就不能再做輪詢了,比如在等輸入,這時你就不能像前面那樣去查詢旗標(biāo)了。碰到這種情況,你可以用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.避免過多的同步,永遠(yuǎn)不要在循環(huán)外面調(diào)用wait

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


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

    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.保持可運行線程數(shù)量盡可能的少的主要技術(shù)是,讓每個線程做少量的工作,然后使用Object.wait等待某個條件發(fā)生,或者使用Thread.sleep()睡眠一段時間,線程不應(yīng)該忙-等busy-wait,即反復(fù)的檢查一個數(shù)據(jù)結(jié)構(gòu),以等待某些事件發(fā)生。除了使程序易受調(diào)度器的變化的影響外,忙等這種做法還會增加處理器的負(fù)擔(dān)
    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 閱讀(4828) 評論(0)  編輯  收藏 所屬分類: Java編程
    主站蜘蛛池模板: 婷婷亚洲天堂影院| 国产精品手机在线亚洲| 伊人婷婷综合缴情亚洲五月| 1024免费福利永久观看网站| 99麻豆久久久国产精品免费| 久久精品国产亚洲AV电影网| 亚洲欧洲自拍拍偷综合| 亚洲大成色www永久网站| 五月天婷亚洲天综合网精品偷| aⅴ在线免费观看| 欧洲人免费视频网站在线| 久久精品免费网站网| 美女裸免费观看网站| 最新亚洲卡一卡二卡三新区| 亚洲日本在线播放| 夜夜亚洲天天久久| 久久久久亚洲精品美女| 人人狠狠综合久久亚洲婷婷| 国产亚洲老熟女视频| 亚洲高清成人一区二区三区| 国产免费卡一卡三卡乱码| 成人毛片免费网站| 精品熟女少妇AV免费观看| 4hu四虎最新免费地址| 亚洲黄色片免费看| 亚洲香蕉免费有线视频| 99re这里有免费视频精品 | 日本免费电影一区| 成人毛片免费网站| 日韩免费观看视频| 免费看一级做a爰片久久| 国产又粗又猛又爽又黄的免费视频| 在线a毛片免费视频观看| 国产美女a做受大片免费| 国产在线a不卡免费视频| 国产99视频精品免费视频7| 国产午夜无码视频免费网站| 国产免费私拍一区二区三区| 亚洲精品视频在线看| 亚洲综合区小说区激情区| 区久久AAA片69亚洲|