Java 具有同步方法和同步语句的对象如何分别类似于监视器和条件关键区域?

Java 具有同步方法和同步语句的对象如何分别类似于监视器和条件关键区域?,java,multithreading,concurrency,synchronization,programming-languages,Java,Multithreading,Concurrency,Synchronization,Programming Languages,从 仅使用同步方法的Java对象(无锁或 同步语句)非常类似于Mesa监视器,其中 每个监视器有一个条件变量的限制(事实上 带有同步语句的对象有时称为 监视器(使用Java) 为什么只使用同步方法的Java对象与Mesa监视器非常相似,在Mesa监视器中,每个监视器有一个条件变量的限制 “只使用同步方法的Java对象”中没有条件变量,对吗?那么,它如何像一个只有一个条件变量的监视器呢 出于同样的原因,Java中的同步语句 循环等待类似于一个CCR,其中 条件已明确。因为通知也是明确的,, Jav

仅使用同步方法的Java对象(无锁或 同步语句)非常类似于Mesa监视器,其中 每个监视器有一个条件变量的限制(事实上 带有同步语句的对象有时称为 监视器(使用Java)

为什么只使用同步方法的Java对象与Mesa监视器非常相似,在Mesa监视器中,每个监视器有一个条件变量的限制

“只使用同步方法的Java对象”中没有条件变量,对吗?那么,它如何像一个只有一个条件变量的监视器呢

出于同样的原因,Java中的同步语句 循环等待类似于一个CCR,其中 条件已明确。因为通知也是明确的,, Java实现不需要重新评估条件(或唤醒) 显式执行此操作的线程)在关键 第节仅包含发生通知的部分

为什么Java中的synchronized语句 循环中的等待类似于CCR(条件临界区),其中条件的重新测试已明确

“因为notify也是显式的,所以Java实现不需要在关键部分的每个出口上重新评估条件(或者唤醒显式执行此操作的线程),而只需要重新评估发生notify的条件”,这是什么意思


谢谢。

所有这些都表明,在Java中,内部锁具有烘焙到它们中的条件。这与ReentrantLock形成对比,在ReentrantLock中,可以使用相同的锁显式地具有单独的条件

如果您有单独的条件,那么您可以向给定的条件发送信号,并且只知道该条件的等待集中的线程将接收该条件。如果您没有单独的条件对象,那么在收到通知后,您必须检查该条件是否适用于您

例如,固定大小的阻塞队列。如果您查看ArrayBlockingQueue,它是使用ReentrantLock实现的,因此放置和获取使用单独的条件对象。如果这是使用队列对象上的内在锁实现的,则必须使用notifyAll来唤醒等待的线程,然后必须测试它们从等待中醒来的条件,以确定它是否与它们相关

下面是一个使用内在锁编写的阻塞队列。如果使用了notify,那么调度程序将唤醒单个线程(因为线程可能正在等待放置或等待获取),它可能与notify相关,也可能与notify无关。要确保通知不会丢失,请通知所有等待的线程:

public class Queue<T>{

    private final int maxSize;
    private List<T> list = new ArrayList<>();
    public Queue(int maxSize) {
        this.maxSize = maxSize;
    }

    public synchronized T take() throws InterruptedException {
        while (list.size() == 0) {
            wait();
         }
         notifyAll();
         return list.remove(0)(
    }

    public synchronized void put(T entry) throws InterruptedException {
        while (list.size() == maxSize) {
            wait();
        }
        list.add(entry);
        notifyAll();
    }
}
公共类队列{
私有最终整数最大值;
私有列表=新的ArrayList();
公共队列(int-maxSize){
this.maxSize=maxSize;
}
public synchronized T take()引发InterruptedException{
while(list.size()==0){
等待();
}
notifyAll();
返回列表。删除(0)(
}
公共同步的void put(T entry)抛出InterruptedException{
while(list.size()==maxSize){
等待();
}
列表。添加(条目);
notifyAll();
}
}

“X为什么与Y相似?”因为它们看起来很相似,也就是说它们的行为方式相似。如果你了解X的行为,那么你就会很快了解Y的行为。你了解“Mesa监视器”或“CCR”吗?如果没有,比较对理解Java监视器没有帮助,任何详细的逐个特性比较对您都没有好处。如果您确实了解这些特性,为什么您不认为它们与Java特性相似?如果您使用一些关于监视器的常识,您实际上不需要了解Mesa:Mesa监视器就是监视器。