用户云卷云舒 发表于 2024-7-7 22:20:17

Java的对象监视器

什么是监视器(Monitor)?

在Java中,监视器(Monitor)是用来实现线程同步的一种机制。每个Java对象都有一个与之关联的监视器,线程可以通过synchronized关键字来获取和开释对象的监视器。监视器的主要作用是确保在同一时刻只有一个线程可以执行同步块或同步方法,从而实现线程的互斥访问。
监视器的构成部门

监视器通常包含以下三个关键部门:

[*]入口集(Entry Set):等待获取监视器锁的线程集合。
[*]全部者线程(Owner Thread):当前持有监视器锁的线程。
[*]等待集(Wait Set):调用了wait()方法并进入等待状态的线程集合。
线程等待的地方


[*]入口集(Entry Set):线程在尝试进入同步块或同步方法时,如果无法获取监视器锁,它们会进入入口集等待。这些线程处于阻塞状态,等待获取监视器锁。
[*]等待集(Wait Set):线程在调用wait()方法后,会开释监视器锁并进入等待集。这些线程处于等待状态,直到被其他线程通过notify()或notifyAll()方法唤醒。
线程状态转换表现图

以下是线程在不同状态之间转换的过程表现图:

[*]新建状态(New):线程被创建,但尚未启动。
[*]可运行状态(Runnable):线程已经启动,可以运行但不一定正在运行。
[*]阻塞状态(Blocked):线程在入口集中,等待获取监视器锁。
[*]等待状态(Waiting):线程在等待集中,等待其他线程通过notify()或notifyAll()唤醒。
[*]超时等待状态(Timed Waiting):线程在等待集中,等待特定时间后被唤醒。
[*]停止状态(Terminated):线程已经结束执行。
示例代码解释

我们通过一个示例代码来解释线程在不同状态之间的转换:
public class MonitorExample {
    private static final Object lock = new Object();

    public static void main(String[] args) {
      Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                try {
                  System.out.println("Thread 1: Acquired lock, entering wait state.");
                  lock.wait();
                  System.out.println("Thread 1: Woken up, reacquired lock.");
                } catch (InterruptedException e) {
                  Thread.currentThread().interrupt();
                }
            }
      });

      Thread thread2 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("Thread 2: Acquired lock, notifying.");
                lock.notify();
                System.out.println("Thread 2: Notified, releasing lock.");
            }
      });

      thread1.start();
      try {
            Thread.sleep(100); // Ensure thread1 starts first and enters wait state
      } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
      }
      thread2.start();
    }
}过程解释


[*]Thread 1 获取监视器锁:

[*]Thread 1 进入同步块并获取监视器锁。
[*]调用lock.wait()方法,Thread 1开释监视器锁并进入等待集。

[*]Thread 2 获取监视器锁:

[*]Thread 2 进入同步块并获取监视器锁(此时Thread 1已在等待集)。
[*]调用lock.notify()方法,唤醒等待集中的一个线程(即Thread 1)。

[*]Thread 2 开释监视器锁:

[*]Thread 2 退出同步块,开释监视器锁。

[*]Thread 1 重新获取监视器锁:

[*]被唤醒的Thread 1从等待集中移动到锁池,重新竞争获取监视器锁。
[*]Thread 1成功获取监视器锁后,从wait()方法返回,继续执行后续代码。

总结


[*]监视器(Monitor):用于实现线程同步,每个Java对象都有一个监视器。
[*]入口集(Entry Set):线程在尝试进入同步块或同步方法时,如果无法获取监视器锁,会进入入口集等待。
[*]等待集(Wait Set):线程在调用wait()方法后,会开释监视器锁并进入等待集,等待被唤醒。
[*]状态转换:线程在不同状态之间转换,包括新建、可运行、阻塞、等待、超时等待和停止状态。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Java的对象监视器