- thread的生命周期
package java.lang; public class Thread implements Runnable { public void start(); public void run(); public void stop(); //已废除,勿使用 public void resume(); //已废除,勿使用 public void suspend(); //已废除,勿使用 public static void sleep(long millis); public static void sleep(long millis,int nanos); public boolean isAlive(); public void interrupt(); public boolean isInterrupted(); public static boolean interrupted(); public void join() throws InterruptedException; ...... }
如图所示 ,Thread生命期,需要注意的是,stop和rusume均已经废除
在这里,着重叙述一下Thread的interrupt方法。
Thread的stop方法已经被停用了,因此interrupt成了一个“终止线程”的方法,但是他又不是用来终止线程用的,比较绕口,简而言之,interrupt是为了结束线程的阻塞状态,观察interrupt的源码发现,其只是为线程设置了一个中断标记位。Thread.interrupt()方法不会中断一个正在运行的线程,这一方法 实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么, 它将接收到一个中断异常 InterruptedException InterruptedException ),从而提早地终结被阻塞状态。因此, 如果线程被上述几种方法阻塞,正确的停止线程方式是设置共享变量,并调用interrupt()(注 意变量应该先设置)。如果线程没有被阻塞,这时调用interrupt()将不起作用;否则,线程就 将得到异常(该线程必须事先预备好处理此状况),接着逃离阻塞状态。在任何一种情况中,最 后线程都将检查共享变量然后再停止.
public class TestInterrupt extends Thread{ private volatile boolean stop=false; @Override public void run(){ System.out.println("thread is running"); try { System.out.println("thread is going to sleep"); if(!stop){ Thread.sleep(10*1000); } System.out.println("after thread sleep"); } catch (InterruptedException e) { // TODO Auto-generated catch block System.out.println("Thread is interupted"); } System.out.println("the thread is over!"); } public static void main(String[]args) throws InterruptedException{ TestInterrupt thread=new TestInterrupt(); thread.start(); Thread.sleep(4*1000); thread.stop=true; thread.interrupt(); Thread.sleep(3*1000); System.out.println("stopping application"); // System.exit(0); } }
打印结果:
thread is running thread is going to sleep Thread is interupted the thread is over! stopping application
由此可见,在线程阻塞后(sleep),使用interrupt()方法,代码try到中断异常,因此执行catch语句,值得一看的是,run()方法会继续从catch下面的语句执行,而不是跳出,因此会打印语句“the thread is over!”由此可见,中断并不会使线程停止,而是从当前sleep状态唤醒往下执行
- thread的基本使用方法
thread有两种方法使用,一种是直接继承Thread类,另一种是实现Runnable接口,比较而言,最常使用的是Runnable因为Java不支持多继承,因此只是继承Thread不够灵活。