文章插图
本节讲解的内容是线程的初始化、线程启动、线程中断、suspend()、resume()、stop()和优雅的关闭线程 。
1.线程初始化和线程的启动首先看下Thread的构造方法:public Thread(Runnable target, String name) {init(null, target, name, 0);}
当然Thread有多个构造方法,都是调用init方法初始化一个线程 。看下init的定义: private void init(ThreadGroup g, Runnable target, String name,long stackSize, AccessControlContext acc,boolean inheritThreadLocals) {...}
包含了所属线程组、Runable对象、线程名称、线程的栈大小、访问控制权和inheritThreadLocals 。当我们通过new关键字创建线程的时候,默认由当前线程来进行空间分配的,而创建出来的线程继承了当前线程的是否为守护线程、线程优先级、contextClassLoader以及ThreadLocal 。创建好的线程对象初始化完成后,在堆内存中等待执行 。注意,创建线程时最好执行线程的名字,方便通过命令jstack分析堆栈信息和问题排查 。如果不手动指定线程名称,默认是Thread-” + nextThreadNum() 。
线程启动是调用start()方法,当前线程同步告诉Java虚拟机,如果线程规划器空闲,应该立即启动线程 。start方法不可以重复调用 。
面试中经常会问到直接运行run()方法会怎么?
首先run方法只是个普通方法,直接运行不会启动一个线程,且当前只有一个主线程(当前线程),程序顺序执行,达不到多线程的目的 。且run方法可以重复执行 。
2.线程的中断当我们执行一个阻塞IO或者长时间没有响应的任务时,我们需要结束线程以避免长时间等待 。Thread.interrupt(),不是立马中断线程,而是设置一个中断标识位 。Java中的阻塞函数比如Thread.sleep,Object.wait,Thread.join等,会不断地轮训检测线程中断标识位是否为true,如果为true,会立马抛出InterruptedException,同时把标识位设置为false 。在下面的程序中,有两个线程,worker和sleeper,线程中断后,观察下输出的标识位:
public class TestInterrupt {public static void main(String[] args) {Thread worker = new Thread(()->{while (true){}}, "work-thread");Thread sleeper = new Thread(()->{while (true){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}, "sleeper-thread");worker.start();sleeper.start();worker.interrupt();sleeper.interrupt();System.out.println("work-thread interrupt is " + worker.isInterrupted());System.out.println("sleeper-thread interrupt is " + sleeper.isInterrupted());}}
java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at net.zhifou.concurrent.base.TestInterrupt.lambda$main$1(TestInterrupt.java:16) at java.lang.Thread.run(Thread.java:748)work-thread interrupt is truesleeper-thread interrupt is false
当中断阻塞状态的sleeper线程,立马抛出了InterruptedException异常,重置中断标识位后输出中断标识位为false,worker线程中断标识位仍为true 。Thread的两个方法,interrupted和isInterrupted,都是返回中断标识位 。我们先看下方法定义:
public static boolean interrupted() {return currentThread().isInterrupted(true);}public boolean isInterrupted() {return isInterrupted(false);}
然后再看下isInterrupted方法的实现:/*** Tests if some Thread has been interrupted.The interrupted state* is reset or not based on the value of ClearInterrupted that is* passed.*/private native boolean isInterrupted(boolean ClearInterrupted);
这个是native方法,看不到实现没关系,看下注释,根据ClearInterrupted的值重置或不重置 。isInterrupted传入的是false,不清除中断的标识位 。而interrupted,传入的是ture,则返回中断标识位后,然后清除中断标识位 。
以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!
「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助:- java开发常用的框架 java框架都有哪些
- python线程池内存耗尽 python进程池内存一直上涨
- 附讲解和思维导图 java代码大全及详解
- java类和对象的基本概念 java中的对象是什么
- java程序入门及开发环境 java官方网站是多少
- mysql创建数据库步骤 java链接mysql数据库的详细步骤
- java开发软件介绍 java开发软件有哪些
- java语法基础 java结束循环的语句
- java中数组的定义与使用 java数组声明和使用
- 教你eclipse创建java程序 eclips安装教程