当前位置: 首页 > 面试题库 >

在对象类中放置wait(),notify()方法背后的概念

耿永寿
2023-03-14
问题内容

我只是很难有时间去了解背后把概念wait()Object类。对于这个问题,为了考虑是否wait()notifyAll()Thread类。

class Reader extends Thread {
    Calculator c;
    public Reader(Calculator calc) {
        c = calc;
    }

    public void run() {
        synchronized(c) {                              //line 9
        try {
            System.out.println("Waiting for calculation...");
            c.wait();
        } catch (InterruptedException e) {}
            System.out.println("Total is: " + c.total);
        }
    }

    public static void main(String [] args) {
        Calculator calculator = new Calculator();
        new Reader(calculator).start();
        new Reader(calculator).start();
        new Reader(calculator).start();
        calculator.start();
    }
}

class Calculator extends Thread {
    int total;
    public void run() {
        synchronized(this) {                     //Line 31
            for(int i=0;i<100;i++) {
                total += i;
            }
             notifyAll();
        }
    } 
}

我的问题是,它可以带来什么变化?在第9行中,我们获取对对象c的锁定,然后执行满足等待条件的等待,该条件是我们需要在使用wait之前获取对对象的锁定的等待条件,对于notifyAll的情况,我们在第31行获取了对Calculator对象的锁定。


问题答案:

我只是很难理解将wait()放在对象类中的概念,出于这个问题,请考虑一下,好像wait()和notifyAll()在线程类中一样

在Java语言中,您要wait()在一个特定的实例上Object–确切地说,是分配给该对象的监视器。如果要向正在等待该特定对象实例的一个线程发送信号,则可以调用notify()该对象。如果要向正在等待该对象实例的所有线程发送信号,请notifyAll()在该对象上使用。

如果wait()notify()Thread相反的位置,则每个线程将必须知道其他每个线程的状态。线程1如何知道线程2正在等待访问特定资源?如果需要调用thread1,thread2.notify()则必须以某种方式找出thread2正在等待的线程。线程需要某种机制来注册它们所需的资源或操作,以便其他线程可以在就绪或可用时发出信号。

在Java中,对象本身是线程之间共享的实体,该实体允许线程彼此通信。线程彼此之间没有特定的知识,它们可以异步运行。他们运行,然后锁定,等待并通知 对象
要访问的 对象 。他们不了解其他线程,也不需要知道它们的状态。他们不需要知道正在等待资源的是thread2
-他们只是通知资源,无论正在等待的人(如果有人)都将得到通知。

然后,在Java中,我们将对象用作线程之间的同步,互斥体和通信点。我们在对象上进行同步,以获取对重要代码块的互斥访问并同步内存。如果我们在等待某种条件的改变(即某些资源可用),我们就在一个对象上。如果我们想唤醒睡眠线程,则通知对象。

// locks should be final objects so the object instance we are synchronizing on,
// never changes
private final Object lock = new Object();
...
// ensure that the thread has a mutex lock on some key code
synchronized (lock) {
    ...
    // i need to wait for other threads to finish with some resource
    // this releases the lock and waits on the associated monitor
    lock.wait();
    ...
    // i need to signal another thread that some state has changed and they can
    // awake and continue to run
    lock.notify();
}

程序中可以有任意数量的锁定对象-
每个锁定对象都锁定特定的资源或代码段。您可能有100个锁对象和只有4个线程。当线程运行程序的各个部分时,它们可以独占访问锁定对象之一。同样,他们不必知道其他线程的运行状态。

这使您可以根据需要任意扩展或缩小软件中运行的线程数。您发现这4个线程在外部资源上阻塞过多,因此可以增加数量。过分用力推动服务器,然后减少正在运行的线程数。锁定对象确保线程之间的互斥和通信与正在运行的线程数无关。



 类似资料:
  • 问题内容: 如何在不是线程的对象上调用和方法?那真的没有道理,对吗? 当然,这一定是有道理的,因为这两种方法可用于所有Java对象。有人可以提供解释吗?我在理解如何使用和进行线程之间通信时遇到麻烦。 问题答案: 锁定是关于保护共享数据。 锁位于要保护的数据结构上。线程是访问数据结构的事物。锁位于数据结构对象上,以防止线程以不安全的方式访问数据结构。 任何对象都可以用作内部锁(与结合使用)。这样,您

  • 问题内容: 我正在尝试检查java中的wait / notify如何工作。 码: 输出返回 我期望在执行notify()时,等待将结束并被打印。但似乎只有完成打印后才能打印。 问题答案: 对象监视器锁需要执行相同锁的单个引用。 在你的榜样,你是对的一个实例,但使用从。相反,您应该使用单个通用锁定对象…例如 输出… 并可能根据线程调度更改位置。 您可以尝试将睡眠排除在障碍之外。这将释放监视器锁定,从

  • 我有个问题。当我在synchronized块中使用时,我有IllegalMonitorStateException。有谁能帮我解决这个问题吗? 我必须这样做,一个线程将发送到第二个线程char,然后这个线程必须等待和第二个线程打印这个char。在第二个线程等待之后,第一个线程再次发送下一个字符 main.java:

  • 1如题,我知道wait,notify,notifyAll一定要在同步代码块中使用。但我有几个问题: 1.如下,我使用ReentrantLock作为锁,为什么会报错? 然后通过Thread类运行run,为什么会提示关于java.lang.IllegalMonitorStateException错误? 2.我使用Task类里的一个静态字符串变量,比如static String mylock="mylo

  • 问题内容: 如上面的示例,如果先进入块,则ThreadB中的后续块将告诉主线程继续。 但是我们不能保证将在)之前执行,如果ThreadB首先进入该块怎么办?会在之前执行,所以会永远挂在那里(因为不再告诉它继续执行)?通常有什么合适的方法来解决这个问题? 问题答案: 您几乎应该总是将谓词与等待/通知一起使用。也就是说,您需要可以检查的条件,例如变量变为true,队列变为空/满等。仅盲目地等待某人调用

  • 问题内容: 似乎该线程都在其他线程调用或在此线程上唤醒。两者之间有什么区别吗? - 编辑 - 我知道一个是通知对象,另一个是中断线程。但是,这两种情况都会导致相同的结果,也就是说,该线程被唤醒,所以我想问的是这两种情况的后果是如何不同的。 问题答案: 当线程在某个监视器上调用notify时,它将唤醒在该监视器上等待的单个线程,但是 哪个 线程被唤醒由调度程序决定。(或者,一个线程可以调用notif