public class Demo1 {
//1.关于编译器智能优化引起的内存可见性问题:
//工作内存=cpu寄存器+缓存
//由于大量重复操作导致编译器优化,t1线程直接读取工作内存,然后t2线程在工作内存修改了变量的值,
// 同步拷贝到了主内存中,但是t1还是直接从工作内存读取数据,无法感知t2早已修改了变量的值。
//2.关于等待唤醒机制:
//程序员无法干预系统对线程调度,但是这样会导致在特殊情况出现“线程饿死",
// 如:某一线程频繁获取释放锁资源,做一些无意义的事情、(队列为空,却要获取)
//此时就可以通过wait方法去让该线程进行阻塞,将cpu的可执行权让给其他线程。等待时机成熟的时候再通知notify该线程。
//wait方法:
//让线程进行阻塞,同时释放锁资源。
//需回顾知识点:static关键字,成员变量,静态方法
//模拟唤醒机制:
public static void main(String[] args) {
final Object locker = new Object();
Thread t1 = new Thread(()->{
synchronized (locker){
System.out.println("等待前");
try {
locker.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("等待后");
});
Thread t2 =new Thread(()->{
synchronized (locker){
Scanner sc=new Scanner(System.in);//防止t2线程先拿到锁资源
System.out.println("唤醒前");
sc.next();
locker.notify();
}
System.out.println("唤醒后");
});
t1.start();
t2.start();
}
//上述代码编译不通过是因为t1和t2的定义在synchronized块外部,
// 导致t1和t2无法被引用。正确的写法应该是在synchronized块内部定义t1和t2线程。
// 同时,定义synchronized块内的变量需要使用final修饰。
0604-JavaSE-线程唤醒机制
于 2024-06-04 22:07:22 首次发布