Java 线程可以具有以下状态:
- NEW(新建):当线程对象被创建时,它处于新建状态。此时它还没有被启动,因此尚未开始执行。
- RUNNABLE(可运行):当线程对象被启动并分配了处理器资源时,它就进入了可运行状态。这意味着线程正在运行或等待 CPU 时间片。
- BLOCKED(阻塞):线程进入阻塞状态是因为它正在等待一个监视器锁,以便进入同步代码块。当其他线程持有锁时,线程就会进入阻塞状态。
- WAITING(等待):线程可以进入等待状态,以等待其他线程执行特定的操作。在这种状态下,线程不会占用处理器时间,直到它被通知或被中断。
- TIMED_WAITING(定时等待):这是一种特殊的等待状态,线程会在一段时间内等待特定的操作。当等待时间到期或者线程被中断时,线程就会返回到可运行状态。
- TERMINATED(终止):线程完成了它的执行或被提前中断,进入终止状态。在这个状态下,线程不会再执行任何代码。
Java 线程唤醒通常涉及两个方法:wait() 和 notify()/notifyAll()。wait() 方法会使当前线程进入等待状态,直到其他线程调用 notify()/notifyAll() 方法唤醒它;而 notify()/notifyAll() 方法则会通知一个/多个正在等待的线程。
下面是一个简单的示例,演示了如何使用 wait() 和 notify() 方法唤醒一个线程:
public class ThreadDemo {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
// 启动线程
myThread.start();
// 主线程休眠1秒钟,确保子线程已经启动
Thread.sleep(1000);
// 唤醒子线程
synchronized (myThread) {
myThread.notify();
}
}
private static class MyThread extends Thread {
@Override
public void run() {
synchronized (this) {
System.out.println("线程开始等待...");
try {
// 进入等待状态
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程被唤醒!");
}
}
}
}
需要注意的是,wait() 和 notify()/notifyAll() 方法只能在 synchronized 代码块中调用,否则会抛出 IllegalMonitorStateException 异常。在调用 wait() 方法时,当前线程会释放锁,其他线程才能获取到锁并执行。因此,在调用 wait() 方法前,需要获取到对象的锁,否则会抛出 IllegalMonitorStateException 异常。
另外,如果有多个线程在等待同一个对象的锁,notify() 方法只能唤醒其中一个线程,而 notifyAll() 方法会唤醒所有等待的线程。
调用notify和wait方法的对象必须是同一个锁对象
notify()方法可以唤醒等待时间最长的线程