스레드는 특정 시점에 하나의 상태에만 있을 수 있습니다.
스레드에는 다음 6가지 상태가 있을 수 있습니다.
New(새로 생성됨): 시작되지 않은 스레드
Runnable(실행 가능): 운영 체제 리소스를 기다려야 하는 실행 가능한 스레드
차단됨: 모니터 잠금을 기다리는 동안 스레드가 차단되었습니다.
Waiting: 다른 스레드가 깨어날 때까지 무기한 대기 중: 다른 스레드가 잠금을 수행할 때까지 기다리는 스레드입니다. 지정된 대기 시간 내 작업
종료(terminating): 종료된 스레드입니다.
스레드의 현재 상태를 확인하려면 getState 메소드를 호출하면 됩니다.
참고: 점선 상자의 상태(모두 영어 대문자)는 Java 스레드 상태입니다.
2. 작업 스레드 상태2.1. 신규 생성 상태(NEW)
Thread 클래스 run() 메서드 재정의
Runnable 인터페이스 구현
Callable 인터페이스 구현
간단한 예에 세 가지 방법이 요약되어 있습니다
public class Demo { public static void main(String[] args) throws ExecutionException, InterruptedException { /** * 1.直接重写run() 或继承Thread类再重写run() */ Thread thread = new Thread() { @Override public void run() { System.out.println("Thread"); } }; // 开启线程 thread.start(); /** * 2.lambda、内部类或线程类方式实现Runnable接口,实现run()方法 * 再交给Thread 类 */ Thread runThread = new Thread(() -> { System.out.println("Runnable"); }); // 开启线程 runThread.start(); /** * 3.lambda、内部类或线程类方式实现Callable接口,实现call()方法 * 再交给Thread 类:FutureTask本质也是Runnable实现类 */ FutureTask<String> futureTask = new FutureTask<String>(() -> { System.out.println("Callable"); return "CallableThread"; }); Thread callThread = new Thread(futureTask); // 开启线程 callThread.start(); // 获取call()方法的返回值 String s = futureTask.get(); System.out.println("call()方法的返回值:"+s); } }
Callable 메서드에서 생성된 스레드만 스레드의 반환 값을 얻을 수 있습니다.
2.2.실행 가능 상태(RUNNABLE)
이 상태는 스레드가 객체를 인스턴스화하고 start() 메서드를 호출한 후 입력되는 상태를 나타냅니다. 스레드는 실행 가능한 상태이며, 프로세서 등의 자원이 있으면 프로그램을 실행할 수 있다.
의 두 단계인 스레드 준비 및 스레드 실행이 포함되지만, Java 스레드 상태에서는 이 두 단계를 통칭하여 Runnable(실행 가능) 상태라고 합니다.
스레드가 준비 상태에서 실행 중 상태로 변경될 때 핵심은 스레드가 CPU 리소스를 확보했는지(CPU 타임 슬라이스) 확인하는 것입니다. 이를 확보한 사람은 누구든지 스레드를 실행하고, 확보하지 못하면 기다리세요. . CPU 타임 슬라이스(실행 시간)가 약 10밀리초 정도로 매우 짧기 때문에 스레드 전환 시간도 매우 짧으며, 준비 상태에서 실행 상태로 변경되는 시간도 매우 짧습니다. 개발 변경이므로 Java에서는 이 두 가지를 전체적으로 간주하여 스레드가 실행될 수 있는지 여부에 초점을 맞추고 다른 상태와 구별하여 스레드 개발을 더욱 단순화합니다. 프로그램이 오랜 시간 동안 실행되어야 하고(예: 무한 루프 작성) 실행이 CPU 시간 조각 내에 완료되지 않으면 스레드는 다음 CPU 시간 조각을 확보한 후에야 다음 CPU 시간 조각을 확보해야 합니다. 프로그램을 계속 실행하며, 잡아내지 못한 경우에는 계속해서 프로그램을 실행할 수 있습니다. 그런 다음 스레드에서 프로그램 실행이 완료될 때까지 계속 잡아야 합니다. 사실 이 시나리오는 이전에 본 적이 있을 것입니다. 예를 들어 여러 스레드가 동일한 프로그램을 실행하고 로그를 동일한 파일에 인쇄하면 서로 다른 스레드의 로그가 혼합되어 문제 해결에 도움이 되지 않습니다. 이 문제를 해결하는 일반적인 방법은 첫째, 서로 다른 스레드의 로그를 서로 다른 파일로 인쇄하는 것입니다. 둘째, 로그 정보를 문자열 개체에 저장하고, 프로그램 종료 시 로그 정보를 한꺼번에 파일에 인쇄합니다. 두 번째 방법은 CPU의 시간 조각을 사용하여 로그 정보 인쇄를 완료하는 것입니다.
참고: 프로그램은 새로 생성된 상태의 스레드에서만 start() 메서드를 호출할 수 있습니다.
새로 생성되지 않은 상태의 스레드에서는 start() 메서드를 호출하지 마세요. 그러면 IllegalThreadStateException 예외가 발생합니다.
2.3. 차단됨 스레드가
monitor차단 상태는 여러 스레드의 동시 액세스에서만 존재하며 스레드 자체가 "대기 중"으로 진입하여 발생하는 후자의 두 가지 유형의 차단과는 다릅니다. 상태 입력 중
동기화된 코드 블록/메소드 입력 중
종료 상태
모니터 잠금 획득
在同步代码块中,线程进入WAITING 状态时,锁会被释放,不会导致该线程阻塞。反过来想下,如果锁没释放,那其他线程就没办法获取锁,也就没办法唤醒它。
进入状态
object.wait()
thread.join()
LockSupport.park()
退出状态
object.notify()
object.notifyall()
LockSupport.unpark()
一般是计时结束就会自动唤醒线程继续执行后面的程序,对于Object.wait(long) 方法还可以主动通知唤醒。
注意:Thread类下的sleep() 方法可以放在任意地方执行;而wait(long) 方法和wait() 方法一样,需要放在同步代码块/方法中执行,否则报异常:java.lang.IllegalMonitorStateException。
进入状态
Thread.sleep(long)
Object.wait(long)
Thread.join(long)
LockSupport.parkNanos(long)
LockSupport.parkNanos(Object blocker, long nanos)
LockSupport.parkUntil(long)
LockSupport.parkUntil(Object blocker, long deadline)
注:blocker 参数为负责此线程驻留的同步对象。
退出状态
计时结束
LockSupport.unpark(Thread)
object.notify()
object.notifyall()
线程执行结束
run()/call() 执行完成
stop()线程
错误或异常>>意外死亡
stop() 方法已弃用。
通过一个简单的例子来查看线程出现的6种状态。
案例
public class Demo3 { private static Object object ="obj"; public static void main(String[] args) throws InterruptedException { Thread thread0 = new Thread(() -> { try { // 被阻塞状态(BLOCKED) synchronized (object){ System.out.println("thread0 进入:等待唤醒状态(WAITING)"); object.wait(); System.out.println("thread0 被解除完成:等待唤醒状态(WAITING)"); } System.out.println("thread0 "+Thread.currentThread().getState()); } catch (InterruptedException e) { e.printStackTrace(); } }); // 新创建状态(NEW) System.out.println(thread0.getName()+":"+thread0.getState()); Thread thread1 = new Thread(() -> { try { System.out.println("thread1 进入:计时等待状态(TIMED_WAITING)"); Thread.sleep(2); System.out.println("thread1 出来:计时等待状态(TIMED_WAITING)"); } catch (InterruptedException e) { e.printStackTrace(); } // 被阻塞状态(BLOCKED) synchronized (object){ System.out.println("thread1 解除:等待唤醒状态(WAITING)"); object.notify(); System.out.println("thread1 解除完成:等待唤醒状态(WAITING)"); } System.out.println("thread1 "+Thread.currentThread().getState()); }); // 新创建状态(NEW) System.out.println(thread1.getName()+":"+thread1.getState()); printState(thread0); printState(thread1); // 可运行状态(RUNNABLE) thread0.start(); // 可运行状态(RUNNABLE) thread1.start(); } // 使用独立线程来打印线程状态 private static void printState(Thread thread) { new Thread(()->{ while (true){ System.out.println(thread.getName()+":"+thread.getState()); if (thread.getState().equals(Thread.State.TERMINATED)){ System.out.println(thread.getName()+":"+thread.getState()); break; } } }).start(); } }
执行结果:简化后的输出结果
Thread-0:NEW
Thread-1:NEW
Thread-0:RUNNABLE
Thread-1:RUNNABLE
thread0 进入:等待唤醒状态(WAITING)
Thread-1:BLOCKED
thread1 进入:计时等待状态(TIMED_WAITING)
Thread-0:BLOCKED
Thread-0:WAITING
……
Thread-0:WAITING
Thread-1:BLOCKED
Thread-1:TIMED_WAITING
……
Thread-1:TIMED_WAITING
Thread-1:BLOCKED
……
Thread-1:BLOCKED
Thread-0:WAITING
……
Thread-0:WAITING
thread1 出来:计时等待状态(TIMED_WAITING)
Thread-0:WAITING
Thread-1:BLOCKED
thread1 解除:等待唤醒状态(WAITING)
Thread-1:BLOCKED
Thread-0:WAITING
Thread-0:BLOCKED
thread1 解除完成:等待唤醒状态(WAITING)
Thread-1:BLOCKED
thread1 RUNNABLE
Thread-0:BLOCKED
Thread-1:TERMINATED
thread0 被解除完成:等待唤醒状态(WAITING)
Thread-0:BLOCKED
thread0 RUNNABLE
Thread-0:TERMINATED
最终的执行结果如图。
注意:因为案例中使用了独立线程来打印不同线程的状态,会出现状态打印稍微延迟的情况。
위 내용은 Java 스레드의 6가지 상태와 라이프사이클은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!