久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

t.interrupt(),t.isInterrupted(),Thread.interrupted()

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

interrupt

public void interrupt()
中斷線程,。

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

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

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

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

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

 

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

interrupted

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

 

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

isInterrupted

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

 

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

t.interrupt()不會(huì)中斷正在執(zhí)行的線程,,只是將線程的標(biāo)志位設(shè)置成true,。但是如果線程在調(diào)用sleep(),join(),wait()方法時(shí)線程被中斷,則這些方法會(huì)拋出InterruptedException,,在catch塊中捕獲到這個(gè)異常時(shí),,線程的中斷標(biāo)志位已經(jīng)被設(shè)置成false了,因此在此catch塊中調(diào)用t.isInterrupted(),Thread.interrupted()始終都為false,
而t.isInterrupted與Thread.interrupted()的區(qū)別是API中已經(jīng)說(shuō)明很明顯了,Thread.interrupted()假如當(dāng)前的中斷標(biāo)志為true,,則調(diào)完后會(huì)將中斷標(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來(lái)終止線程則在捕獲的InterruptedException中return
        }
        while (counter < 100000 &&!done) {
            System.out.println(counter++);
            //在主線程中調(diào)用stoppable.interrupt()之前為false,假如之后沒(méi)有調(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,之后只有第一個(gè)會(huì)顯示為true,之后全為false
            
            
//調(diào)用Thread.interrupted()一次會(huì)清除線程的中斷標(biāo)志位,因此以后都為false
            if(Thread.interrupted()==true){
                try{
                    //Thread.interrupted()會(huì)清除中斷標(biāo)志位,顯然這里面只會(huì)調(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();//不會(huì)中斷正在執(zhí)行的線程,原因是因?yàn)閕nterrupt()方法只設(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,也不會(huì)被主線程捕獲
            //要使主線程能夠捕獲這個(gè)RuntimeException請(qǐng)參見(jiàn)另外一篇文章
            //地址:http://www./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是一個(gè)會(huì)睡上一段時(shí)間的Thread,至于睡多長(zhǎng)時(shí)間,,這要由構(gòu)造函數(shù)的參數(shù)決定,。Sleeper的run( )的sleep( )可以因時(shí)限到期而返回,也可以被interrupt( )打斷,。catch語(yǔ)句在報(bào)告中斷的同時(shí),,會(huì)一并報(bào)告isInterrupted( )。當(dāng)有別的線程調(diào)用了本線程的interrupt( )時(shí),,會(huì)設(shè)置一個(gè)標(biāo)記以表示這個(gè)這個(gè)線程被打斷了,。當(dāng)本線程捕獲這個(gè)異常的時(shí)候,會(huì)清除這個(gè)標(biāo)志,。所以catch語(yǔ)句會(huì)永遠(yuǎn)報(bào)告說(shuō)isInterrupted( )是false,。這個(gè)標(biāo)記是用來(lái)應(yīng)付其它情況的,或許在沒(méi)出異常的情況下,,線程要用它來(lái)檢查自己是不是被中斷了,。
Joiner是另一個(gè)線程,它調(diào)用了Sleeper的join( ),,所以它要等Sleeper醒過(guò)來(lái),。main( )創(chuàng)建了兩個(gè)Sleeper分派給兩個(gè)Joiner。你會(huì)發(fā)現(xiàn),,不論Sleeper是被打斷還是正常結(jié)束,,Joiner都會(huì)隨Sleeper一道結(jié)束。





2,,如何終止一個(gè)線程:
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( )方法能看到它(否則它會(huì)使用本地的緩存值)。這個(gè)線程的"任務(wù)"是打印10,000個(gè)數(shù)字,,所以當(dāng)counter >= 10000或有人要它停下來(lái)的時(shí)候,,它就結(jié)束了。注意requestStop( )不是synchronized,,因?yàn)閟top既是boolean(改成true是一個(gè)原子操作)又是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來(lái)終止線程則在捕獲的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
    }
}

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

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


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

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("模擬此線程做耗時(shí)工作");
        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("在將對(duì)象入隊(duì)列 "+workItem);
                enqueue(workItem);
            }
        };
        child.start();
        child.join();//dead lock
        
    }
    
    
}


4.保持可運(yùn)行線程數(shù)量盡可能的少的主要技術(shù)是,讓每個(gè)線程做少量的工作,,然后使用Object.wait等待某個(gè)條件發(fā)生,,或者使用Thread.sleep()睡眠一段時(shí)間,線程不應(yīng)該忙-等busy-wait,,即反復(fù)的檢查一個(gè)數(shù)據(jù)結(jié)構(gòu),,以等待某些事件發(fā)生。除了使程序易受調(diào)度器的變化的影響外,,忙等這種做法還會(huì)增加處理器的負(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 閱讀(2996) 評(píng)論(0)  編輯  收藏 所屬分類: Java編程

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多