package com.boot.admin;
import java.text.SimpleDateFormat;
import java.util.concurrent.TimeUnit;
public class WaitNotify {
static boolean flag = true;
static Object lock = new Object();
public static void main(String[] args) throws Exception {
Thread waitThread = new Thread(new Wait(), "WaitThread");
waitThread.start();
TimeUnit.SECONDS.sleep(1);
Thread notifyThread = new Thread(new Notify(), "NotifyThread");
notifyThread.start();
}
static class Wait implements Runnable {
public void run() {
// 加锁,拥有lock的Monitor
synchronized (lock) {
// 当条件不满足时,继续wait,同时释放了lock的锁
while (flag) {
try {
System.out.println(Thread.currentThread() + " flag is true. wait
@ " + new SimpleDateFormat(" HH:
mm:
ss ").format(new Date()));
lock.wait();
} catch (InterruptedException e) {
}
}
// 条件满足时,完成工作
System.out.println(Thread.currentThread() + " flag is false. running
@ " + new SimpleDateFormat(" HH:
mm:
ss ").format(new Date()));
}
}
}
static class Notify implements Runnable {
public void run() {
// 加锁,拥有lock的Monitor
synchronized (lock) {
// 获取lock的锁,然后进行通知,通知时不会释放lock的锁,
// 直到当前线程释放了lock后,WaitThread才能从wait方法中返回
System.out.println(Thread.currentThread() + " hold lock. notify @ " +
new SimpleDateFormat("HH:mm:ss").format(new Date()));
lock.notifyAll();
flag = false;
SleepUtils.second(5);
}
// 再次加锁
synchronized (lock) {
System.out.println(Thread.currentThread() + " hold lock again. sleep
@ " + new SimpleDateFormat(" HH:
mm:
ss ").format(new Date()));
SleepUtils.second(5);
}
}
}
}
输出如下(输出内容可能不同,主要区别在时间上)。
Thread[WaitThread,5,main] flag is true. wait @ 22:23:03
Thread[NotifyThread,5,main] hold lock. notify @ 22:23:04
Thread[NotifyThread,5,main] hold lock again. sleep @ 22:23:09
Thread[WaitThread,5,main] flag is false. running @ 22:23:14
package com.test;
public class MyThreadPrinter2 implements Runnable {
private String name;
private Object prev;
private Object self;
private MyThreadPrinter2(String name, Object prev, Object self) {
this.name = name; // A B C
this.prev = prev; // c a b
this.self = self; // a b c
}
@Override
public void run() {
int count = 10;
while (count > 0) {
// 加锁,锁的钥匙是prev
synchronized (prev) {
// 一把锁,锁的钥匙是self变量
synchronized (self) {
System.out.print(name);
count--;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 唤醒另一个线程,但是也需要把本线程执行完后,才可以释放锁
self.notify(); //a b c
}
try {
// 释放对象锁,本线程进入休眠状态,等待被唤醒
prev.wait(); //睡觉觉了,等待被叫醒吧 // c a b
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws Exception {
Object a = new Object();
Object b = new Object();
Object c = new Object();
MyThreadPrinter2 pa = new MyThreadPrinter2("A", c, a);
MyThreadPrinter2 pb = new MyThreadPrinter2("B", a, b);
MyThreadPrinter2 pc = new MyThreadPrinter2("C", b, c);
new Thread(pa).start();
// 这样才可以保证按照顺序执行
Thread.sleep(10);
new Thread(pb).start();
Thread.sleep(10);
new Thread(pc).start();
Thread.sleep(10);
}
}