目录
一、整体图表
二、补充知识
下图取之Java线程状态
如上图所示:
- 总共分为六个状态(运行态和就绪态归为运行态)
三、具体方法
3.1 wait方法
3.1.1定义
让线程进入等待并且释放锁。
3.1.2注意
- 当前线程必须持有该对象的锁
wait
必须被唤醒后或者设置时间进入队列才能继续执行接下来的操作
3.1.3使用方式
public static Object object = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new Thread1());
thread3.start();
}
static class Thread1 implements Runnable {
@Override
public void run() {
//比如在同步代码块或者方法里且得到该对象的锁
synchronized (object) {
System.out.println(Thread.currentThread().getName() + " is running.");
try {
//对象进入等待
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " get the lock.");
}
}
}
3.2 notify方法
3.2.1定义
唤醒任意一个等待的线程。
3.2.2注意
- 当前线程必须持有该对象的锁
notify
后会唤醒一个正在等待的线程- 但是当前线程不会马上放弃锁的持有权,而是在同步代码执行完毕后才会释放锁
3.2.3 使用方式
//步骤
//1.先让线程0执行然后进行等待
//2.再让线程1执行然后通过 notify 唤醒0线程(因为等待队列只有0线程)
//3.线程1执行结束后会执行线程0
public static Object object = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new Thread1());
Thread thread2 = new Thread(new Thread2());
thread1.start();
Thread.sleep(1000);
thread2.start();
}
static class Thread1 implements Runnable {
@Override
public void run() {
synchronized (object) {
System.out.println(Thread.currentThread().getName() + " running.");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " get the lock.");
}
}
}
static class Thread2 implements Runnable {
@Override
public void run() {
synchronized (object) {
System.out.println(Thread.currentThread().getName() + " is running.");
object.notify();
System.out.println(Thread.currentThread().getName() + " invoke notify()");
System.out.println(Thread.currentThread().getName() + " release the lock.");
}
}
}
//结果:
Thread-0 running.
Thread-1 is running.
Thread-1 invoke notify()
Thread-1 release the lock.
Thread-0 get the lock.
3.3 notifyAll
3.3.1定义
唤醒所有在等待的锁。
3.3.2注意
- 当前线程必须持有该对象的锁
notify
后会唤醒所有在等待的锁- 但是当前线程不会马上放弃锁的持有权,而是在同步代码执行完毕后才会释放锁
3.3.3 使用方式
步骤
- 先让线程0以及线程1执行然后进行等待
- 再让线程2执行然后通过
notifyAll
唤醒所有线程并进入终止状态(TERMINATED
) - 线程0,1从等待状态(
WAITING
)进入阻塞(BLOCKED
)状态 - 线程1获得锁进入运行状态(
RUNNABLE
) - 之后线程1进入终止状态(
TERMINATED
),线程0进入运行状态(RUNNABLE
),之后终止(TERMINATED
)
执行顺序:
public static Object object = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new Thread1());
Thread thread2 = new Thread(new Thread2());
Thread thread3 = new Thread(new Thread3());
thread1.start();
thread2.start();
Thread.sleep(1000);
thread3.start();
}
static class Thread1 implements Runnable {
@Override
public void run() {
synchronized (object) {
System.out.println(Thread.currentThread().getName() + " running.");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " get the lock.");
}
}
}
static class Thread2 implements Runnable {
@Override
public void run() {
synchronized (object) {
System.out.println(Thread.currentThread().getName() + " running.");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " get the lock.");
}
}
}
static class Thread3 implements Runnable {
@Override
public void run() {
synchronized (object) {
System.out.println(Thread.currentThread().getName() + " is running.");
object.notifyAll();
System.out.println(Thread.currentThread().getName() + " invoke notifyAll()");
System.out.println(Thread.currentThread().getName() + " release the lock.");
}
}
}
结果:
Thread-0 running.
Thread-1 running.
Thread-2 is running.
Thread-2 invoke notifyAll()
Thread-2 release the lock.
Thread-1 get the lock.
Thread-0 get the lock.