先贴一段在通常情况下使用wait()/notify()方法的示例demo
public class Test {
public static void main(String[] args) {
Object lock = new Object();// 锁对象
// target线程,此线程将被挂起
Thread target = new Thread(() -> waited(lock));
target.start();
// action线程,用此线程唤醒上述target线程
Thread action = new Thread(() -> wakeUp(lock));
action.start();
}
private static void waited(Object lock) {
synchronized (lock) {
int times = 0;
try {
while (true) {// 循环打印数字,直至线程被挂起
System.out.println(times);
times++;
if (times == 5) {// 当循环到第五次时,挂起线程
System.out.println("目标线程被挂起");
lock.wait();
}
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static void wakeUp(Object lock) {
try {
Thread.sleep(10000);
synchronized (lock) {
lock.notify();
System.out.println("唤醒目标线程");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
几乎在所有的教程里,使用wait()/notify()方法时,都是要求程序员先new一个Object对象作为调用目标,在调用Object对象的wait()/notify()方法前要先给对象加锁。
设想了一下,如果线程调用的方法都是静态方法(整个业务逻辑里没有new任何对象),并且这些静态方法都在同一个class里面,那么直接给静态方法加上synchronized关键字(众所周知,直接在静态方法上添加synchronized关键字,实际上就是给静态方法所在的class文件加了锁),然后直接使用“类名.class”来调用Class对象wait()/notify(),按理说应该也是可以的。因为网上没有相关的测试代码,就自己写了一个测试了一下。
最后的结论是可以的。
贴一下代码
public class Test {
public static void main(String[] args) {
// target线程,此线程将被挂起
Thread target = new Thread(() -> waited());
target.start();
// action线程,用此线程唤醒上述target线程
Thread action = new Thread(() -> wakeUp());
action.start();
}
private synchronized static void waited() {
int times = 0;
try {
while (true) {// 循环打印数字,直至线程被挂起
System.out.println(times);
times++;
if (times == 5) {// 当循环到第五次时,挂起线程
System.out.println("目标线程被挂起");
Test.class.wait();
}
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private synchronized static void wakeUp() {
try {
Thread.sleep(10000);
Test.class.notify();
System.out.println("唤醒目标线程");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
两种写法的运行效果完全一致
其实在真实的业务逻辑中,几乎不可能出现整个项目中不new任何对象的情况,也很难保证所有的静态方法都在同一个class文件中。但不排除某些奇葩公司的奇葩面试题里会问到这个。