【java】线程

描述 java 线程的基本概念

java 线程状态

java.lang.Thread.State 定义了 java 线程中的状态,目前 JDK12 有 NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED 6 种状态。可以通过 getState() 方法来获取线程的状态。

  1. NEW
    创建后尚未启动的线程处于这个状态

  2. RUNNABLE
    RUNNABLE 表示线程在等待调度或者正在运行,调用 start() 方法后就处于这个状态

  3. BLOCKED
    阻塞状态,当尝试进入一个 synchronized 语句块/方法时,锁已经被其它线程占有,就会被阻塞,直到另一个线程走完临界区或发生了相应锁对象的 wait() 操作后,它才有机会去争夺进入临界区的权利。
    处于 BLOCKED 状态的线程,即使对其调用 thread.interrupt() 也无法改变其阻塞状态,因为 interrupt() 方法只是设置线程的中断状态,即做一个标记,不能唤醒处于阻塞状态的线程。

  4. WAITING
    无限期等待状态,状态通常是指一个线程拥有对象锁后进入到相应的代码区域后,调用相应的“锁对象”的 wait() 方法操作后产生的一种结果。
    变相的方法还有 Thread.join(), Unsafe.park() 等

  5. TIMED_WAITING
    限期等待,同 WAITING,不过有超,进入的方法有 Thread.sleep(), 带时间版本的 wait(),Thread.join(), Unsafe.park() 等

  6. TERMINATED
    线程已终止。

“阻塞”与“等待”的区别:

  • “阻塞”状态是等待着获取到一个独占锁,进入“阻塞”状态都是被动的,离开“阻塞”状态是因为其它线程释放了锁,不阻塞了
    例如等待其他线程退出 synchronized 块
  • “等待”状态是在等待一段时间,或者唤醒动作的发生,进入“等待”状态是主动的
    例如 wait() 就等待 notify 或 notifyAll 被调用;join 等待一个线程结束;park 等待 unpark 被调用

WAITING 状态还可以细化为

  • 休眠 (sleeping),调用了 Thread.sleep()
  • 等待 (on object monitor),调用了 wait()
  • 驻留 (parking),调用了 Unsafe.park()

线程操作

  1. public static Thread currentThread()
    获取正在运行的线程的 thread 对象

  2. public static native void yield()
    提示调度器,当前线程放弃时间片。调度器也可以忽略这个提示。

  3. public static native void sleep(long millis) throws InterruptedException
    public static void sleep(long millis, int nanos) throws InterruptedException
    使线程进入睡眠,线程不会释放它持有的 monitors

  4. public static boolean interrupted()
    public boolean isInterrupted()
    测试线程是否被中断过,中断状态会被 reset,static 版本针对当前线程

  5. public static int activeCount()
    估计当前线程有多少同组的活动线程

  6. public synchronized void start()
    启动线程

  7. public void interrupt()
    中断线程,并设置中断状态位
    如果线程在 WAITING 状态,interrupt() 会中断等待状态,线程会收到 InterruptedException
    如果线程阻塞在 InterruptibleChannel,则 channel 会被关闭,线程会收到 ClosedByInterruptException
    如果线程阻塞在 java.nio.channels.Selector, 则直接返回

  8. public final native boolean isAlive()
    测试线程是否“活着”

  9. public final void setPriority(int newPriority)
    public final int getPriority()
    设置/获取线程优先级

  10. public final synchronized void setName(String name)
    public final String getName()
    设置/获取线程名

  11. public final synchronized void join(final long millis)
    public final synchronized void join(long millis, int nanos)
    public final void join() throws InterruptedException
    等待 Thread 对象关联的线程结束,用 wait() 实现

  12. public final void setDaemon(boolean on)
    public final boolean isDaemon()
    将线程变为守护线程。线程分守护线程和用户线程两种,如果只存在守护线程,没有用户线程的运行,JVM 退出

  13. public final void checkAccess()
    检查当前线程是否有权限修改目标 Thread 关联的线程

  14. public StackTraceElement[] getStackTrace()

  15. public static void dumpStack()
  16. public static native boolean holdsLock(Object obj)
  17. public static Map<Thread, StackTraceElement[]> getAllStackTraces()
    这些用于分析问题有用