Java 线程相关问题

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()的区别 ?

  1. start() 方法来启动线程, 并在新线程中运行 run()方法, 真正实现了多线程运行。 这时无需等待 run 方法体代码执行完毕, 可以直接继续执行下面的代码; 通过调用 Thread 类的 start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行, 然后通过此 Thread 类调用方法 run()来完成其运行操作, 这里方法 run()称为线程体, 它包含了要执行的这个线程的内容, run()方法运行结束, 此线程终止。 然后 CPU 再调度其它线程。
  2. 直接调用 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);
}

猜你喜欢

转载自blog.csdn.net/jcsyl_mshot/article/details/80245601