Java并发-5.线程状态

2019-05-28 13:21:46 浏览数 (1)

Java线程有6种状态

Java线程在运行的声明周期有6中不同的状态,给任一时刻,线程只能处于其中一种状态:

状态

说明

NEW

初始状态,线程被构建的,但是还没有调用start()方法

RUNNABLE

运行状态,这里包括操作系统中的就绪和运行两种状态,Java统称“运行中”

BLOCKED

阻塞,标识线程阻塞于锁

WAITING

等待,标识当前线程需要等待其他线程作出一些特定操作(通知或中断)

TIME_WAITING

超时等待,不同于WAITING,可在指定时间后自行返回

TERMINATED

中止,标识线程已经执行完毕

示例代码: ThreadState

代码语言:javascript复制
/**
 * Java线程的各种状态
 *
 * @author pengjunzhe
 */
public class ThreadState {

    public static void main(String[] args) {
        new Thread(new TimeWaiting(), "TimeWaitingThread").start();
        new Thread(new Waiting(), "WaitingThread").start();
        new Thread(new Blocked(), "BlockedThread-1").start();
        new Thread(new Blocked(), "BlockedThread-2").start();
    }

    /**
     * 该线程不断进行睡眠
     */
    static class TimeWaiting implements Runnable {
        @Override
        public void run() {
            while (true) {
                SleepUtils.second(100);
            }
        }
    }

    /**
     * 该线程在Waiting.class实例上等待
     */
    static class Waiting implements Runnable {
        @Override
        public void run() {
            while (true) {
                synchronized (Waiting.class) {
                    try {
                        Waiting.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 阻塞的线程,在Blocked.class实例上加锁后,不会释放锁
     */
    static class Blocked implements Runnable {
        @Override
        public void run() {
            synchronized (Blocked.class) {
                while (true) {
                    SleepUtils.second(100);
                }
            }
        }
    }
}

SleepUtils

代码语言:javascript复制
import java.util.concurrent.TimeUnit;

public class SleepUtils {
    public static final void second(long seconds) {
        try {
            TimeUnit.SECONDS.sleep(seconds);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

查看线程pid:

代码语言:javascript复制
$jps
48316 ThreadState
48317 Jps

查看线程状态:

代码语言:javascript复制
$jstack 48316
"TimeWaitingThread" #13 prio=5 os_prio=31 tid=0x00007fe47383b000 nid=0xa703 waiting on condition [0x000070000928f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at java.lang.Thread.sleep(Thread.java:340)
        at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
        at com.junzerg.threads.SleepUtils.second(SleepUtils.java:8)
        at com.junzerg.threads.ThreadState$TimeWaiting.run(ThreadState.java:24)
        at java.lang.Thread.run(Thread.java:748)
"WaitingThread" #14 prio=5 os_prio=31 tid=0x00007fe47481b000 nid=0x5903 in Object.wait() [0x0000700009392000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x000000076ae4b270> (a java.lang.Class for com.junzerg.threads.ThreadState$Waiting)
        at java.lang.Object.wait(Object.java:502)
        at com.junzerg.threads.ThreadState$Waiting.run(ThreadState.java:38)
        - locked <0x000000076ae4b270> (a java.lang.Class for com.junzerg.threads.ThreadState$Waiting)
        at java.lang.Thread.run(Thread.java:748)
"BlockedThread-1" #15 prio=5 os_prio=31 tid=0x00007fe470853800 nid=0xa403 waiting on condition [0x0000700009495000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at java.lang.Thread.sleep(Thread.java:340)
        at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
        at com.junzerg.threads.SleepUtils.second(SleepUtils.java:8)
        at com.junzerg.threads.ThreadState$Blocked.run(ThreadState.java:55)
        - locked <0x000000076ae4f498> (a java.lang.Class for com.junzerg.threads.ThreadState$Blocked)
        at java.lang.Thread.run(Thread.java:748)

Java线程状态之间的变化

  • 线程实例化之后进入初始状态(NEW)
  • 调用Thread.start()方法后进入运行状态(RUNNABLE)
    • 操作系统调度线程在就绪(READY)和运行中(RUNNING)状态中切换
    • JVM能用yield()方法使进程从运行中切换到就绪,其他不能干涉
  • 线程可以在RUNNABLE和WAITING间切换:
    • 以下方法可以使进程从RUNNABLE切换到WAITING:
      • Object.wait()
      • Object.join()
      • LockSupper.park()
    • 以下方法使进程从WAITING切换到RUNNABLE:
      • Object.notify()
      • Object.notifyAll()
      • LockSupper.unpark(Thread)
  • 线程可以在RUNNABLE和TIMED_WAITING间切换:
    • 以下方法使进程从RUNNABLE切换到TIMED_WAITING:
      • Thread.sleep(long)
      • Object.wait(long)
      • Object.join(long)
      • LockSupper.parkNanos()
      • LockSupper.parkUntil()
    • 以下方法使线程从TIME_WAITING切换到到RUNNABLE:
      • Object.notify()
      • Object.notifyAll()
      • LockSupper.unpark(Thread)
      • 超时时间到
  • 线程可以在RUNNABLE和BLOCKED中切换
    • 以下方法线程从RUNNABLE切换到BLOCKED:
      • 等待进入synchronize方法
      • 等待进入synchronize块
    • 以下方法线程从阻塞切换到RUNNABLE:
      • 获取到锁
  • 线程执行完成后进入中止状态(TERMINATED)

0 人点赞