1.Java 中 interrupted() 和 isInterrupted()方法的区别?
interrupt()方法用于中断线程【终止线程】。是用来设置中断状态的。返回true说明中断状态被设置了而不是被清除了。调用该方法的线程的状态将被置为”中断”状态。
interrupted()作用于当前线程,返回的是当前线程的中断状态同时清除线程的中断标志。
isInterrupt():线程是否中断
二个方法都是判断线程是否停止的方法。
1.Interrupted()是静态方法, 后者是非静态方法。 interrupted 是作用于当前正在运行的线程, isInterrupted 是作用于调用该方法的线程对象所对应的线程。(线程对象对应的线程不一定是当前运行的线程。 例如我们可以在 A 线程中去调用B 线程对象的 isInterrupted 方法, 此时, 当前正在运行的线程就是 A 线程。 )
2.前者会将中断状态清除而后者不会。
拓展阅读
Thread.sleep、Thread.join、Object.wait、LockSupport.park等在检查到线程的中断状态时,会抛出InterruptedException,同时会清除线程的中断状态.
对于InterruptedException的处理,可以有两种情况: (1)外层代码可以处理这个异常,直接抛出这个异常即可 (2)如果不能抛出这个异常,比如在run()方法内,因为在得到这个异常的同时,线程的中断状态已经被清除了,需要保留线程的中断状态,则需要调用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 关闭程序并且退出。 一个守护线程创建的子线程依然是守护线程。
守护线程的一个典型例子就是垃圾回收器。
4.ThreadLocal 的原理
ThreadLocal 相 当 于 一 个 容 器 , 用 于 存 放 每 个 线 程 的 局 部 变 量 。ThreadLocal 实例通常来说都是 private static 类型的。 ThreadLocal 可以给一个初始值, 而每个线程都会获得这个初始化值的一个副本, 这样才能保证不同的线程都有一份拷贝。
通常使用ThreadLocal.set() 线程自己使用的对象保存到自身的线程对象中, 其他线程是访问不到的。各个线程中ThreadLocal.get()访问的是不同的对象。 当用户调 用 ThreadLocal 对 象 的 set(Object o) 时 , 该 方 法 则 通 过Thread.currentThread() 获 取 当 前 线 程 , 将 变 量 存 入 线 程 中 的ThreadLocalMap 类的对象内, Map 中元素的键为当前的 threadlocal 对象,而值对应线程的变量副本。
public void set(T value) {
//获取当前线程
Thread t = Thread.currentThread();
//得到当前线程的map对象
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this,firstValue);
}