一、复习上一节内容
- wait()方法、中断正在运行的线程会抛出java.lang.InterruptedException、当线程调用共享对象的wait()方法时,当前线程只会释放当前共享变量的锁,不会释放该线程所持有的其他共享变量的锁。
- wait(long timeout,int nanos)实现、wait(0)内部调用了wait()方法、notify()随机唤醒、notifyAll()全部唤醒、join方法、sleep方法、yield方法,以及sleep与yield方法的区别
二、线程中断interrupt
- 使用interrupt()方法去中断线程,isInterrupted()来检测这个线程是否被中断了
package com.ruigege.threadFoundation1;
public class SubThreadInterruptedState {
public static void main(String[] args) throws InterruptedException{
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
while(!Thread.currentThread().isInterrupted()) {
System.out.println("子线程没有中断");
}
System.out.println("子线程虽然中断了,但是并没有结束");
}
});
thread1.start();
Thread.sleep(5);//保证子线程能够执行起来
thread1.interrupt();//中断子线程,可以理解为时间片这里不给它,一会再给它因此子线程会持续运行结束,这函数就是一个表姐而已
System.out.println(thread1.isInterrupted());
thread1.join();
System.out.println("主线程结束");
}
}
![3.1](https://img-blog.csdnimg.cn/2020103000011957.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDYzMDA1MA==,size_16,color_FFFFFF,t_70#pic_center)
- 解释:
- void interrupt()方法的执行可以理解为做一个标记而已,而不是真的去停止了该线程,该线程还会继续执行下去直到结束
- boolean isInterrupted()方法是用来检测该标记的,如果被中断了,就返回true;否则返回false
- static boolean Interruped()方法也是用来检测该标记的,但是多个一个步骤,就是去除这个印记,一会举例说明。
public static boolean Interrupted(){
return Thread.currentThread().isInterrupted(true);
}
1.那么调用interrupt()方法的时候,会在线程的哪里中断呢?
- 线程在调用wait()、sleep()、join()方法的时候,如果其他线程给与它interrupt方法,那么会在前面那三种方法处中断
- 我们直接举个上述的例子,比如执行一个线程,让他中间sleep几秒钟,那么此时使用interrupt来打断,在sleep函数这里抛出一个java.lang.InterruptedException
package com.ruigege.threadFoundation1;
public class InterruptThreadWhenSleeping {
public static void main(String[] args) throws InterruptedException {
Thread threadOne = new Thread(new Runnable() {
@Override
public void run(){
try {
System.out.println("子线程开始了,并开始睡眠几秒");
Thread.sleep(3000);
System.out.println("睡眠结束");
}catch(InterruptedException e) {
e.printStackTrace();
}
}
});
threadOne.start();
Thread.sleep(1000);
threadOne.interrupt();
threadOne.join();
}
}
![3.2](https://img-blog.csdnimg.cn/20201030232758889.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDYzMDA1MA==,size_16,color_FFFFFF,t_70#pic_center)
- 在写这个例子的时候,我想要使用run() throws InterruptedException,但是编译不通过,于是改用try...catch...捕捉异常,百度了一下ava run()方法无法throws 异常,其实没看懂,应该是JVM的原理,还得继续学啊。
- boolean isInterrupted()和boolean interrupted()两个方法的区别在于,前一个就是检测到底中断标志的,后一个也是检测中断标志,但是检测完之后,会去掉该标志,我们直接举例
package com.ruigege.threadFoundation1;
public class isInterruptedAndinterrupted {
public static void main(String[] args) throws InterruptedException {
Thread threadOne = new Thread(new Runnable() {
@Override
public void run() {
for(;;) {
}
}
});
threadOne.start();
threadOne.interrupt();
System.out.println("子线程isInterrupted:"+threadOne.isInterrupted());
System.out.println("子线程Interrupted:"+threadOne.interrupted());
System.out.println("主线程Interrupted:"+Thread.interrupted());
System.out.println("子线程isInterrupted:"+threadOne.isInterrupted());
threadOne.join();
}
}
![3.3](https://img-blog.csdnimg.cn/20201030234903643.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDYzMDA1MA==,size_16,color_FFFFFF,t_70#pic_center)
- 注意第二个,为什么时false,我们要看源码,return Thread.currentThread().isInterrupted(),所以虽然子线程对象调用,但是这是在主线程中运行该语句,所以是false
- 下面来在看一个
package com.ruigege.threadFoundation1;
public class SubThreadInvokeTag {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while(!Thread.currentThread().isInterrupted()) {
}
System.out.println("子线程isInterruped()状态:"+Thread.currentThread().isInterrupted());
System.out.println("子线程interruped()状态:"+Thread.currentThread().interrupted());
System.out.println("子线程isInterruped()状态:"+Thread.currentThread().isInterrupted());
}
});
thread.start();
thread.interrupt();
System.out.println("主线程isInterrupted状态"+Thread.currentThread().isInterrupted());
thread.join();
}
}
![3.4](https://img-blog.csdnimg.cn/20201030235937791.png#pic_center)
三、源码: