我市精神文明建设的门户网站,常用网站建设技术是什么,济南网站建设内容设计,芜湖服装网站建设目录
一、等待和通知机制的概念
二、wait() 方法
2.1 wait() 方法的使用
2.2 超时等待
2.3 异常唤醒
2.4 唤醒等待的方法
三、notify() 方法
四、notifyAll() 方法
五、wait 和 sleep 的对比 一、等待和通知机制的概念
1#xff09;什么是等待和通知机制#xff1f…目录
一、等待和通知机制的概念
二、wait() 方法
2.1 wait() 方法的使用
2.2 超时等待
2.3 异常唤醒
2.4 唤醒等待的方法
三、notify() 方法
四、notifyAll() 方法
五、wait 和 sleep 的对比 一、等待和通知机制的概念
1什么是等待和通知机制 线程是抢占式执行的无法预知线程之间的执行顺序。 但有时程序员也希望能合理协调多个线程的执行顺序。 因此在 Java 中使用了等待(wait)和通知(notify)机制用于在应用层面上干预多个线程的执行顺序。 应当注意的是干预执行顺序并不是干预系统的线程调度策略操作系统内核中的线程调度仍是无序的而是使被指定的线程主动放弃被系统调度的机会直到其他线程对被指定的线程发出通知这个线程才再次参与系统的线程调度。排队都不排了自然也就轮不到它了
2使用等待和通知机制主要涉及以下三个方法wait()让线程进入等待状态。notify()唤醒在当前对象上等待的一个线程。notifyAll()唤醒在当前对象上等待的所有线程。以上三个方法都是 Object 类的方法。 二、wait() 方法
2.1 wait() 方法的使用
1wait() 方法需要配合 synchronized 关键字使用 wait() 方法必须在 synchronized 修饰的代码块或方法中使用否则会抛出 IllegalMonitorStateException 异常。
2使用锁对象调用 wait() 方法 虽然wait() 是 Object 类的方法任何对象都可以调用该方法。 但是为了实现等待通知机制要求调用 wait() 的对象必须是锁对象且这个锁对象要与 synchronized 指定的锁对象一致。
3wait() 方法具体做了什么 wait() 方法主要执行了以下三个操作 1释放当前的锁。2使当前线程进入等待队列。3通过某些条件被唤醒时重新尝试获取当前锁。
代码演示wait()使用方法和使用结果 public static void main(String[] args) throws InterruptedException {//创建锁对象Object locker new Object();System.out.println(wait前);//在 synchronized 代码块中调用 wait 方法synchronized (locker){// wait 方法是由锁对象调用的调用后线程释放锁进入等待队列locker.wait();}System.out.println(wait后);}//运行结果
wait前
...程序没有执行完毕线程一直在 wait 。
2.2 超时等待
有时间限制的等待 上文中的代码除非有其他线程唤醒否则执行后会一直处于 wait 的状态这就使得程序陷入了“停摆”状态。 在部分场景中我们可以使用带时间参数的 wait() 方法来规避这个问题。即使没有其他线程唤醒 wait wait 仍会在超过规定时间后自动唤醒避免了程序的“停摆”。
代码演示带时间参数的wait()使用方法和使用结果 public static void main(String[] args) throws InterruptedException {//创建锁对象Object locker new Object();System.out.println(wait前);//在 synchronized 代码块中调用 wait 方法synchronized (locker){// wait 方法是由锁对象调用的调用后线程释放锁进入等待队列locker.wait(3000);//3秒后线程被唤醒}System.out.println(wait后);}//运行结果
wait前
wait后成功执行完毕。
2.3 异常唤醒
代码演示通过抛出异常唤醒wait public static void main(String[] args) {//创建锁对象Object locker new Object();Thread t1 new Thread(()-{System.out.println(wait前);//在 synchronized 代码块中调用 wait 方法synchronized (locker){// wait 方法是由锁对象调用的调用后线程释放锁进入等待队列try {locker.wait();} catch (InterruptedException e) {e.printStackTrace();}//3秒后线程被唤醒}System.out.println(wait后);});t1.start();//抛出异常清除中断标志唤醒t1线程。t1.interrupt();}//运行结果
wait前
wait后
java.lang.InterruptedException抛出了InterruptedException后线程被唤醒继续执行。
2.4 唤醒等待的方法
唤醒等待的方法有三种1 超时等待超过了 wait() 方法指定的等待时间。 2异常唤醒通过其他线程调用该等待线程的 interrupted() 方法抛出异常唤醒。3notify() 方法其他线程调用该对象的 notify() 方法。 三、notify() 方法
1notify() 方法有什么作用 notify() 方法可以唤醒等待的线程。
2notify() 也要写在 synchronized 修饰的代码块或方法中 notify() 方法也是 Object 类的方法所以任何对象都可以调用。 在操作系统的原生 API 中也有 wait() 和 notify() 方法。与 wait() 方法不同操作系统的原生 API 没有要求 notify() 必须在 synchronized 修饰的代码块或方法中使用。 但是应注意在 Java 中还是特别约定了 notify() 方法也是要放在 synchronized 修饰的代码块或方法中的。
3wait() 和 notify() 方法是通过锁对象联系的 一个锁对象调用的 wait() 只能被同一个锁对象调用的 notify() 唤醒。 如果唤醒时同一个锁对象有多个线程正在等待此时只会随机唤醒一个。
4执行 notify() 方法后锁在什么时候释放 在 notify() 方法后当前线程不会马上释放锁对象而是等到线程执行完 notify() 方法所在的代码块或方法后才会释放锁对象。 这也是 Java 中约定 notify() 方法要放在 synchronized 修饰的代码块或方法中的原因。
代码演示通过 notify 唤醒wait public static void main(String[] args) throws InterruptedException {//创建一个锁对象Object locker new Object();//创建一个线程Thread t1 new Thread(()-{System.out.println(wait前);//打印wait前后等待synchronized (locker){try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}//被唤醒后打印wait后System.out.println(wait后);});t1.start();//休眠两秒保证t1线程进入等待状态。Thread.sleep(2000);//打印notify前后唤醒System.out.println(notify前);synchronized (locker){locker.notify();//在出代码块前打印notify后。System.out.println(notify后);}}//运行结果
wait前
notify前
notify后
wait后打印wait前之后进入阻塞等待直到被notify唤醒之后才打印了wait后。 四、notifyAll() 方法
notifyAll() 方法有什么作用 唤醒这个锁对象上所有等待的线程。 有多个线程使用同一个锁对象 wait 当对这个锁对象使用 notifyALL() 方法时所有在等待的线程都会唤醒。 但是需要注意在唤醒之后由于需要重新获取锁此时被唤醒的线程必然要进行锁竞争所以这些被唤醒的线程并不是同时就开始执行各自的代码了而仍然是有先后顺序的执行顺序依旧是随机的。 五、wait 和 sleep 的对比
相同点都会使线程阻塞等待。
不同点wait() 方法sleep() 方法用途用于线程间通信。用于线程阻塞等待。用法 是 Object 类中的方法 需要在被 synchronized 修饰的代码块或方法中使用。 是 Tread 类中的静态方法 方法的使用与 synchronized 无关。 状态 被调用后当前线程进入 BLOCK 状态并释放锁。 被调用后当前线程进入 TIME_WAIT 状态。唤醒 通常通过 notify 唤醒 可以通过超时或抛出异常唤醒 通常按设定的时间唤醒 可以通过抛出异常唤醒 阅读指针 - 《单例模式的两种实现“饿汉模式”和“懒汉模式”》
JavaEE 单例模式的两种实现“饿汉模式”和“懒汉模式”-CSDN博客介绍了什么是单例模式和单例模式的两种实现模式。重点介绍了单例模式中“懒汉模式”在多线程下的实现。https://blog.csdn.net/zzy734437202/article/details/134785459