前面我看过不少的博客,部分有说建立线程有多种方式,但JDK1.8源码Thread中有这么一段话.ide
There are two ways to create a new thread of execution.One is to declare a class to be a subclass of Thread,The other way to create a thread is to declare a class that implements the Runnable interface.
官方给出的说明是本质上只有两种方式:1.继承Thread类,2.实现Runnable接口。但还有不少外在的表现形式,例如lambda表达式,线程池等。this
public class NewThread { /*扩展自Thread类*/ private static class UseThread extends Thread{ @Override public void run() { super.run(); // do my work; System.out.println("I am extendec Thread"); } } /*实现Runnable接口*/ private static class UseRunnable implements Runnable{ @Override public void run() { // do my work; System.out.println("I am implements Runnable"); } } public static void main(String[] args) throws InterruptedException, ExecutionException { UseThread useThread = new UseThread(); useThread.start(); UseRunnable useRunnable = new UseRunnable(); new Thread(useRunnable).start(); }
直接上代码:spa
public class EndThread { private static class UseThread extends Thread{ public UseThread(String name) { super(name); } @Override public void run() { String threadName = Thread.currentThread().getName(); System.out.println(threadName+" interrrupt flag ="+isInterrupted()); while(!isInterrupted()){ //while(!Thread.interrupted()){ System.out.println(threadName+" is running"); System.out.println(threadName+"inner interrrupt flag =" +isInterrupted()); } System.out.println(threadName+" interrrupt flag ="+isInterrupted()); } } public static void main(String[] args) throws InterruptedException { Thread endThread = new UseThread("endThread"); endThread.start(); Thread.sleep(20); endThread.interrupt();//中断线程,其实设置线程的标识位true } }
stop()、suspend()也能中止线程,那么为何要将其标注为Deprecated(过期)的方法呢?缘由就是这种方式是抢占式的,好比:有一个任务在写文件,文件的总大小为10M,如今写了5M,忽然收到stop()的中断,致使线程忽然中止,那么这样就破坏了文件的完整性。使用interrupt()方法的好处就是,调用该方法时会给线程的中断标志位设置为true,并把中断线程的决定权交给线程本身,这种方式就是协做式,等任务处理完再结束。
相同点:调用interrupt()方法时,二者都能获取线程的中断标志位状态为true 不一样点:Thread.interrupt()在判断完以后会将中断标志位重置为false
public class EndRunnable { private static class UseRunnable implements Runnable{ @Override public void run() { while(!Thread.currentThread().isInterrupted()) { System.out.println(Thread.currentThread().getName() + " I am implements Runnable."); } System.out.println(Thread.currentThread().getName() +" interrupt flag is "+Thread.currentThread().isInterrupted()); } } public static void main(String[] args) throws InterruptedException { UseRunnable useRunnable = new UseRunnable(); Thread endThread = new Thread(useRunnable,"endThread"); endThread.start(); Thread.sleep(20); endThread.interrupt(); } }
当线程的执行体中出现了sleep、await、join等会抛出interruptException异常的方法时,须要特别注意,就例以下面的程序。线程调用interrupt方法时,线程的执行体会捕获到interruptException异常,进入到catch中,这时会将线程的中断标志位重置为false。这样作的意义在于:若是不重置为false的话,线程收到中断请求立马就结束了那么与stop方法没有区别了,若是重置为false,程序能够在catch中作未完成的工做,如释放资源等,作完这些收尾的工做以后再手动的调用一次interrupt()方法,结束线程。线程
/** *类说明:阻塞方法中抛出InterruptedException异常后,若是须要继续中断,须要手动再中断一次 */ public class HasInterrputException { private static class UseThread extends Thread{ public UseThread(String name) { super(name); } @Override public void run() { while(!isInterrupted()) { try { Thread.sleep(100); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName() +" in InterruptedException interrupt flag is " +isInterrupted()); //资源释放 //interrupt(); e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " I am extends Thread."); } System.out.println(Thread.currentThread().getName() +" interrupt flag is "+isInterrupted()); } } public static void main(String[] args) throws InterruptedException { Thread endThread = new UseThread("HasInterrputEx"); endThread.start(); Thread.sleep(500); endThread.interrupt(); } }
设置标志标志位,经过判断标志位来中断线程,这种方式的不合理因素在于,若是线程执行体中的方法长时间被阻塞,致使循环阻塞,中断标志位失效。code
/** *类说明:设置标志位中断线程 */ public class HasInterrputException { private static class UseThread extends Thread{ private volatile boolean flag = false; public UseThread(String name) { super(name); } public void setFlag(boolean flag) { this.flag = flag; } @Override public void run() { while(!flag) { try { Thread.sleep(100); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName() +" in InterruptedException interrupt flag is " +isInterrupted()); //资源释放 //interrupt(); e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " I am extends Thread."); } System.out.println(Thread.currentThread().getName() +" interrupt flag is "+isInterrupted()); } } public static void main(String[] args) throws InterruptedException { Thread endThread = new UseThread("HasInterrputEx"); endThread.start(); Thread.sleep(500); ((UseThread) endThread).setFlag(true); } }
jdk源码对Thread类定义了6个状态,分别为:blog
public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; }