本意是在主线程中测试一下wait方法和notify方法,主线程wait,子线程唤醒主线程。为了体现明显的效果,进行了一段时间的睡眠。
通过实例去调用sleep
import lombok.extern.slf4j.Slf4j;
import java.util.Stack;
@Slf4j
public class Test {
public static void main(String[] args) {
Stack<String> stack = new Stack<>();
Thread a = new Thread(() ->{
log.debug("========================");
synchronized (stack) {
log.debug("test2 唤醒主线程!");
stack.notify();
}
}, "test2");
try {
log.debug("========================");
log.debug("test2 开始睡眠!");
a.sleep(10000);
log.debug("test2 启动!");
a.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (stack){
try {
log.debug("主线程暂停!");
stack.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
结果直接就卡在主线程,不在往下走。
修改之后,使用正确的方式
import lombok.extern.slf4j.Slf4j;
import java.util.Stack;
@Slf4j
public class Test {
public static void main(String[] args) {
Stack<String> stack = new Stack<>();
Thread a = new Thread(() ->{
log.debug("========================");
log.debug("test2 线程睡眠一下,在启动");
try {
Thread.sleep(1000);
synchronized (stack) {
log.debug("test2 唤醒主线程!");
stack.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "test2");
log.debug("========================");
log.debug("test2 启动!");
a.start();
synchronized (stack){
try {
log.debug("主线程暂停!");
stack.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
控制台打印结果
总结
1、实例对象调用静态方法时,编译不出错而且可以正常运行,是可以调用的。实际上还是通过类在调用。不过发现了这个没关注到的点。
2、java的静态变量也叫做类变量,它开始于类的创建,结束于类的消亡。静态方法一般都是通过类之间访问,不应该通过类实例访问静态成员。虽然使用实例调用编译不会报错,但是实际上都是在通过类在调用,并不代表该静态方法特属于某一个实例。