进程的最小执行单元,一个程序中不同的执行路径,就是多个线程。
方法调用和线程调用:
run方法级别调用:
调用run,本方法和run方法是同一个线程
start方法线程级别调用
本地方法继续执行,同时会产生一个分支线程来执行start(线程中的run方法)
start方法最终会调用run方法,start调用操作系统创建线程,然后由操作系统启动,状态为RUNNABLE,然后回调我们重写的run方法。
线程是cpu调度的,cpu没有线程的概念,自身是死循环,不断的从内存中获取指令然后运行,没有就歇着。
方法1:
Thread.sleep(). 交出cpu使用权让给别的线程执行,倒计时结束,自己回到就绪状态,等待cpu调度
方法2:
Thread,yeild() 礼让线程,写在哪个线程体中,哪个线程体从运行状态切换为就绪状态,回到等待队列中,和其他线程在同一个起跑线上,暂时让出cpu
方法3:
线程对象.join();
方法4:
线程中断:interrupt();
原理:
当前线程中断标志改为true,如果阻塞状态会抛出异常,会将中断标志重置为false(将阻塞改为就绪)
线程中断的相关方法:
线程中断可以使线程从阻塞状态变为就绪状态,如果被中断的线程正在运行,不会起作用(最起码表面看起来是这样的,不会马上中断自己)
线程的runnable状态包含就绪状态和运行状态,线程中断主要是为了打断正在阻塞的线程,如你设置了倒计时2天,你想提前结束这个倒计时,可以使用interrupt来实现。
早期Java提供了stop方法暴力停止线程,但是已废弃。
interrupt和stop的区别:
interrupt对stop进行了改进,更加人性化,线程中断的目的并不是将线程杀死或停止,而是让线程不再继续等待,继续执行代码,中断后会抛出intercuptException,然后在根据业务编写后续的代码
我们定义标记,不满足标记表明终止程序,这是一种方法boolean ,java 提供的interrept也是该思想(底层是0和1)。例子1:如果下面代码没有中断标记,是死循环
例子2:终止当前线程,那么上面的判断就是中断状态,将结束循环,如果调用了intercept,相当于给当前执行的线程一个中断信号,不会马上中断,什么时候中断呢?等待当前线程执行完毕。
打印一下中断标记更加直观:
例子3:thread.interrept()做的事情:
将isInterrupt()置为true,isInterrept是volatile修饰的,所以循环这里可以看到
注意:如果判断的是死循环,那么这里的中断将没有任何意义:
打印
例子4: interrupted的使用 线程复位
Interrupted调用时会返回当前的中断状态,返回之后就会将此状态重置为false
Thread.interrupted () 属于当前线程的操作,是当前状态中断信号对外界的回应,表示该线程得到了中断信号,但是不会马上结束。回到初始状态,重置
例子5 interruprException
阻塞状态下的线程被打断会抛出interruptException异常,但是线程仍然会继续执行,变量a还在不断累加,要不要继续执行,在catch里操作即可控制
——————————————
线程生命周期图: