线程的启动方式和如何安全的中断线程
线程的基础概念应该都有了解了吧
认识Java里的线程
java天生就是多线程的
新启动线程的三种方式
package org.dance.day1; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * 新启动线程的三种方式 * @author ZYGisComputer */ public class NewThread { /** * 继承Thread类 */ private static class UseThread extends Thread{ @Override public void run() { System.out.println("继承自Thread类!"); super.run(); } } /** * 实现Runnable接口 */ private static class UseRunnable implements Runnable{ @Override public void run() { System.out.println("实现自Runnable接口!"); } } /** * 实现Callable接口 * 可以有返回值 */ private static class UseCallable implements Callable<Boolean>{ @Override public Boolean call() throws Exception { System.out.println("实现自Callable接口!"); return true; } } public static void main(String[] args) throws ExecutionException, InterruptedException { // 启动线程一 UseThread useThread = new UseThread(); useThread.start(); // 启动线程二 UseRunnable useRunnable = new UseRunnable(); Thread thread = new Thread(useRunnable); thread.start(); // 启动线程三 UseCallable useCallable = new UseCallable(); FutureTask<Boolean> futureTask = new FutureTask<Boolean>(useCallable); Thread thread1 = new Thread(futureTask); thread1.start(); // 获取Callable的返回值 get方法是阻塞的 Boolean aBoolean = futureTask.get(); System.out.println(aBoolean); } }
线程有启动就有停止
线程自然终止:线程自然执行完毕终止或者抛出未处理异常;
在早期的jdk中有stop(),resume(),suspend()方法,现在已经不建议使用了,stop()会导致线程不会正确释放资源,suspend()挂起时,不会释放资源,容易导致死锁,而且这些方法太过于强势
java线程是协作式的,而非抢占式
那么,我们改如何中断一个线程呢
调用一个线程的interrupt()方法中断一个线程,并不是强制关闭这个线程,只是跟这个线程打个招呼,将线程中断标志位置为true,线程是否中断,由线程本身决定
isInterrupted()判定当前线程是否处于中断状态
static方法interrupted()判定当前线程是否处于中断状态,同时中断标志位改为false
方法里如果抛出InterruptedException,线程的中断标志位会被复位成false,如果确实是需要中断线程,要求我们自己在catch语句块再次调用interrupt()方法
package org.dance.day1; /** * 停止线程 * * @author ZYGisComputer */ public class StopThread { /** * 继承Thread类的中断 */ private static class UseThread extends Thread { public UseThread(String threadName) { super(threadName); } @Override public void run() { // 获取当前线程的名称 String name = Thread.currentThread().getName(); // 如果这里是true的话 那么这个子线程是可以完全不理会主线程发出的中断请求的 但是如果是调用stop方法的话那么会直接停止 // 所以说java是协作式的不是抢占式的 while (!isInterrupted()) { System.out.println("当前线程:" + name); } System.out.println(name + " interrupt flag is " +isInterrupted()); } } /** * 如果是实现自Runnable接口,那么就不能像继承Thread类一样中断了 */ private static class UseRunnable implements Runnable{ @Override public void run() { String name = Thread.currentThread().getName(); // 需要获取线程然后中断 while (!Thread.currentThread().isInterrupted()){ System.out.println("当前线程:" + name); } System.out.println(name + " interrupt flag is "+ Thread.currentThread().isInterrupted()); } } public static void main(String[] args) throws InterruptedException { // stopThread(); stopRunnable(); } /** * 继承Thread类中断 * @throws InterruptedException */ public static void stopThread() throws InterruptedException { UseThread stopThread = new UseThread("StopThread"); stopThread.start(); Thread.sleep(20); // 尝试去中断线程 stopThread.interrupt(); } /** * 实现Runnable接口中断 * @throws InterruptedException */ public static void stopRunnable() throws InterruptedException { UseRunnable useRunnable = new UseRunnable(); Thread stopThread = new Thread(useRunnable, "StopThread"); stopThread.start(); Thread.sleep(20); stopThread.interrupt(); } /** * Callable 中断同 Runnable 中断方式一致 */ }
异常中断:
线程中如果有中断异常,需要在异常中再次中断,因为抛出中断异常,线程的中断标志位会被重新置为false
package org.dance.day1; /** * 异常中断 * @author ZYGisComputer */ public class HasInterruptException { /** * 继承Thread类的中断 */ private static class UseThread extends Thread { public UseThread(String threadName) { super(threadName); } @Override public void run() { // 获取当前线程的名称 String name = Thread.currentThread().getName(); while (!isInterrupted()) { try { Thread.sleep(100); } catch (InterruptedException e) { System.out.println(name + " interrupt flag is " +isInterrupted()); // 含有中断异常的 需要在中断异常中再次中断 否则因为中断异常 线程中断标志位会被重新置为false interrupt(); e.printStackTrace(); } System.out.println(name); } System.out.println(name + " interrupt flag is " +isInterrupted()); } } public static void main(String[] args) throws InterruptedException { UseThread useThread = new UseThread("HasInterruptException"); useThread.start(); Thread.sleep(500); useThread.interrupt(); } }
作者:彼岸舞
时间:2020\09\14
内容关于:并发编程
本文来源于网络,只做技术分享,一概不负任何责任