Thread 重要方法总结

1.isAlive()
   线程已经调用了start方法且没有结束
   返回true时,线程对应于Runnable,Waiting,Timed_Waiting,Blocked四种State, 不要以为 只是对应于Runnable状态

   返回false时,线程对应于New,Terminated两种状态
  
2.isInterrupted()
  线程是否interrupted status 是否为true,注意interrupted为true只是表明该线程的interrupt方法被调用了,该方法只是把interrupted状态设为true,建议线程终止,并不具有强制结束线程的功能,线程结束与否要看线程的run中对该状态为true时如何响应.如下的代码演示了线程当该状态变为true时退出运行.当然,线程可以忽略该状态.所以依靠interrupt方法来终止线程是不可行的.
当处于interrupted状态的线程调用sleep,join,wait方法时会抛出 InterruptedException 异常,而且该状态会被重置为false

//被interrupt后终止线程
 public void run() {
    while(!isInterrupted()){
        //do task
    }
 }


 public void run() {
    while(true){
//不管着怎样,线程只管执行,注意interrupt会导致阻塞(wait,sleep,join)的线程抛出异常,代码要根据业务逻辑争取处理异常(忽略异常或终止等)
        //do task
    }
 }

3.
interrupt

该方法只会对alive的线程起作用,而且具体的行为根据线程所处的状态会有所不同
a.如果线程正在因为调用了wait,sleep,join(包括有时间参数的版本)方法处于阻塞状态,该方法会导致线程(不是interrupt方法)抛出InterruptedException异常,而且interrupt status会被设置为false(等于没调用)
b.如果线程处于NIO的InterruptibleChannel或者Selector的阻塞状态,则interrupt status会被设置为true,前者会抛出一个异常,后者会返回一个非零值
c.其余所有情况下的对该方法调用都会设置interrupt status为true

interrupt()方法被调用了,该方法只是把interrupted状态设为true,建议线程终止,并不具有强制结束线程的功能,线程结束与否要看线程的run中对该状态为true时如何响应

看代码对情况a的说明:

import java.util.Random;

public class TestThreadStatus {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Thread t = new TestThread();
	 

		try {

			t.start();
			 
			try {
				while(true){
					try {
						Thread.sleep(5000);
						t.interrupt();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

class TestThread extends Thread {
	public void run() {
		try {
			while (true) {
				try {
					// 为true,所以下列三个方法的调用(当thread已经被interrupt或者稍后被interrupt)都会抛出
					//InterruptedException
					 System.err.println("Thread is interrupted = "+this.isInterrupted()); 
					 
					 int random = (int)(new Random().nextDouble()*3);
					 
					//当线程调3个方法任意一个都会导致异常,并清空interrupted
					 if(random == 0){
						 System.err.println("Interrupt a thread blocked by wait()");
						 synchronized("lock"){
							   "lock".wait(); //说明wait除了被notify之外,还有可能被interrupt释放
						 }
					 } else if(random == 1){
						 System.err.println("Interrupt a thread blocked by sleep()");
						 Thread.sleep(20000); 
					 } else {
						 System.err.println("Interrupt a thread blocked by join()");
						 Thread tt = new OneThread();
						 tt.start();//一定要启动,下一行的join才会阻塞
						 tt.join();//等待线程tt die,如果tt线程状态为new或者terminated(alive=false),都会马上返回
					 }
					 

				} catch (InterruptedException e) {
					e.printStackTrace();
					System.err.println("Thread is interrupted  = "+this.isInterrupted());// 为false,因为已经被清空
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

class OneThread extends Thread {
	public void run() {
		try {
			while (true) {
				try {
					Thread.sleep(5000);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}



4.join
  t.join();
  t.join(1000);
  调用该方法后,当前线程会阻塞直到线程t结束或者等待指定时间.但当前线程被interrupt(调用join前或者后)会抛出InterruptedException异常

该方法可以用于等待若干个线程执行完毕后再进行后续动作

5.setDaemon
  设置线程为守护线程或者用户线程,必须在线程调用start前设置.
  当只剩下守护线程时,JVM可以exit
(Java Virtual Machine exits when the only threads running are all
     * daemon threads. )
6.yield
  Thread.yield(),

  当前线程进入Runnable状态,不会释放锁,这就造成当前线程可能在调用yield会马上重新获得执行权.经过测试低优先级的线程也会获得执行权这与网上说法不一致,猜测为多核所致.

7.sleep
  Thread.sleep(time); 当前线程会休息指定的时间段,进入Time_Waiting状态,不会释放锁.
 


8.interrupted
  Thread.interrupted() 当前线程的是否interrupted 状态为true.并且该方法会清空该状态.
 

Yield和Sleep的异同

1) sleep()使当前线程进入Time_Waiting状态,所以执行sleep()的线程在指定的时间内肯定不会执行;yield()只是使当前线程重新回到Runnable状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。

2) sleep()可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会; yield()只能使优先级大于等于它的线程有执行的机会。,蓝色字体内容待商榷

你可能感兴趣的:(thread)