1.Java 中 interrupted() 和 isInterrupted()方法的区别?
interrupt()方法用于中断线程【终止线程】。是用来设置中断状态的。返回true说明中断状态被设置了而不是被清除了。调用该方法的线程的状态将被置为"中断"状态。
public static boolean interrupted():作用于当前线程(当前线程指运行 thread.interrupted()方法的线程,而不是thread 线程),返回的是当前线程的中断状态同时清除线程的中断标志。
public boolean isInterrupt():测试线程 Thread 对象是否已经是中断
//例1:当前线程是main 线程 ,中断操作发生在thread 线程上
public class t12 {
public static void main(String[] args) {
try {
MyThread12 thread = new MyThread12();
thread.start();
Thread.sleep(500);
thread.interrupt();
System.out.println("是否终止1? =" + thread.interrupted());
System.out.println("是否终止2? =" + thread.interrupted());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("-------------end-------------");
}
}
class MyThread12 extends Thread {
public void run() {
for (int i = 0; i < 50000; i++) {
System.out.println("i = " + i);
}
}
}
//是否终止1?=false
//是否终止2?=false
//例2:当前线程同样是main 线程,中断操作发生在main 线程上
public class t13 {
public static void main(String[] args) {
Thread.currentThread().interrupt();
System.out.println("是否终止1? =" + Thread.interrupted());
System.out.println("是否终止2? =" + Thread.interrupted());
System.out.println("----------end-----------");
}
}
二个方法都是判断线程是否停止的方法。
1.Interrupted()是静态方法, 后者是非静态方法。 interrupted 作用当前运行的线程,isInterrupt() 作用于调用该方法的线程。
2.Interrupted()会将中断状态清除而isInterrupted()不会。
拓展阅读
Thread.sleep、Thread.join、Object.wait、LockSupport.park等在检查到线程的中断状态时(Thread.currentThread().isInterrupted()等方法),会抛出InterruptedException,同时会清除线程的中断状态.
对于InterruptedException的处理,可以有两种情况: (1)外层代码可以处理这个异常,直接抛出这个异常即可 (2)如果不能抛出这个异常,比如在run()方法内,因为在得到这个异常的同时,线程的中断状态已经被清除了,需要保留线程的中断状态,则需要调用Thread.currentThread(). interrupt()
class MyThread extends Thread {
......
......
public void run() {
try {
while(!Thread.currentThread().isInterrupted()) {
//当达到队列容量时,在这里会阻塞
//put的内部会调用LockSupport.park()这个是用来阻塞线程的方法
//当其他线程,调用此线程的interrupt()方法时,会设置一个中断标志
//LockSupport.part()中检测到这个中断标志,会抛出InterruptedException,并清除线程的中断标志
//因此在异常段调用Thread.currentThread().isInterrupted()返回为false
ArrayBlockingQueue.put(somevalue);
}
} catch (InterruptedException e) {
//由于阻塞库函数,如:Object.wait,Thread.sleep除了抛出异常外,还会清除线程中断状态,因此可能在这里要保留线程的中断状态
Thread.currentThread().interrupt();
}
}
2.Java创建线程之后,直接调用 start()方法和 run()的区别 ?
- start() 方法来启动线程, 并在新线程中运行 run()方法, 真正实现了多线程运行。 这时无需等待 run 方法体代码执行完毕, 可以直接继续执行下面的代码; 通过调用 Thread 类的 start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行, 然后通过此 Thread 类调用方法 run()来完成其运行操作, 这里方法 run()称为线程体, 它包含了要执行的这个线程的内容, run()方法运行结束, 此线程终止。 然后 CPU 再调度其它线程。
- 直接调用 run()方法的话, 会把 run() 方法当作普通方法来调用, 会在当前线程中执行 run()方法, 而不会启动新线程来运行 run()方法。程序还是要顺序执行, 要等待 run 方法体执行完毕后, 才可继续执行下面的代码。
3.用户线程和守护线程有什么区别
当我们在 Java 程序中创建一个线程, 它就被称为用户线程。 将一个用户线程 设 置 为守 护 线 程 的 方法 就 是 在 调 用 start() 方 法 之 前 , 调 用 对象 的setDamon(true)方法。 一个守护线程是在后台执行并且不会阻止 JVM 终止的线程, 守护线程的作用是为其他线程的运行提供便利服务。 当没有用户线程在运行的时候, JVM 关闭程序并且退出。 一个守护线程创建的子线程依然是守护线程。
守护线程的一个典型例子就是垃圾回收器。