几种常见的创建线程的方法
实现Runnable接口
/*实现Runnable接口*/ private class UseRun implements Runnable{ @Override public void run() { System.out.println("I am implements Runnable"); } public static void main(String[] args) { UseRun useRun = new UseRun(); new Thread(useRun).start(); } }
实现Callable接口,允许有返回值
/*实现Callable接口,允许有返回值*/ private static class UseCall implements Callable<String>{ @Override public String call() throws Exception { System.out.println("I am implements Callable"); return "CallResult"; } public static void main(String[] args) { //第一步,先new一个类 UseCall useCall = new UseCall(); //第二步,用FutureTask类包装下,注意:FutureTask类继承了Runnable接口 FutureTask<String> futureTask = new FutureTask<>(useCall); //第三步,启动 new Thread(futureTask).start(); //第四步,得到线程返回的结果,注意这里是阻塞式的。必须执行完线程才能拿到结果 System.out.println(futureTask.get()); } }
继承Thread类创建线程
public class MyThread extends Thread{//继承Thread类 public void run(){ //重写run方法 } } public class Main { public static void main(String[] args){ new MyThread().start();//创建并启动线程 } }
如何让线程停止?
怎么样才能让Java里的线程安全停止工作呢?
线程自然终止:自然执行完或抛出未处理异常,
stop() (停止线程),resume() (继续执行线程), suspend() (挂起线程 ) 已不建议使用,stop()会导致线程不会正确释放资源,suspend()容易导致死锁。
java线程是协作式,而非抢占式
- 调用一个线程的interrupt() 方法中断一个线程,并不是强行关闭这个线程,只是跟这个线程打个招呼,将线程的中断标志位置为true,线程是否中断,由线程本身决定。
- isInterrupted() 判定当前线程是否处于中断状态。
- static方法interrupted() 判定当前线程是否处于中断状态,同时中断标志位改为false。
-
方法里如果抛出InterruptedException,线程的中断标志位会被复位成false,如果确实是需要中断线程,要求我们自己在catch语句块里再次调用interrupt()。
package com.kakaluote.multi_threaddemo.Multi_001.safeend; /** * @Description * @auther 刘中华 * @create 2019-04-03 21:44 * * 测试的目的:我们起一个线程,想中途把它关闭,一般使用变量flag=trun/false的方法。关闭就变成false,结束循环,这样关闭时不严谨的。 * 我们一般采用isInterrupted()的方法,这个方法是判断当前线程是否挂起。挂起返回true,否则返回false。 * 发现的问题:当我们调用中断线程之后,发现线程还在跑???为什么呢? * 楼主发现线程还在运行证明不是线程结束造成的,对线程的interrupt是对线程处在sleep,wait,join状态的时候才起作用。 * InterruptException不interrupt()方法抛出的,interrupt()只改变线程的中断状态, * sleep,wait,join的内部会不停的检查线程中断状态,如果它们检查到线程处于中断状态,就抛出异常中断线程。 * 如果你的线程不处于这3个状态中,调用interrupt不会中断线程,或者说不会马上中断线程, * 如果后面的代码有让线程进入上面3个状态的其中一个,线程会马上抛出InterruptException而中断, * 因为你之前的interrupt()调用改变了线程的内部状态。 */ public class EndRunnable { private static class UseRunnable implements Runnable{ @Override public void run() { String threadName = Thread.currentThread().getName(); while(!Thread.currentThread().isInterrupted()) { //让线程抛出InterruptedException异常。测试 当InterruptedException异常的时候会把isInterrupted() 设置为false,我们需要再次调用下中断 try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); Thread.currentThread().interrupt(); } System.out.println(threadName+" is run!"); } System.out.println(threadName+" interrput 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(2); endThread.interrupt(); } }