Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在非线程的对象上调用wait()和notify()方法?_Java_Multithreading_Wait_Notify - Fatal编程技术网

Java 如何在非线程的对象上调用wait()和notify()方法?

Java 如何在非线程的对象上调用wait()和notify()方法?,java,multithreading,wait,notify,Java,Multithreading,Wait,Notify,如何在非线程的对象上调用wait()和notify()方法?这真的没有道理,是吗 当然,这是有意义的,因为这两种方法适用于所有Java对象。有人能解释一下吗?我无法理解如何使用wait()和notify()在线程之间通信。您可以使用wait()和notify()来同步逻辑。例如 synchronized (lock) { lock.wait(); // Will block until lock.notify() is called on another thread. } // So

如何在非线程的对象上调用
wait()
notify()
方法?这真的没有道理,是吗

当然,这是有意义的,因为这两种方法适用于所有Java对象。有人能解释一下吗?我无法理解如何使用
wait()
notify()
在线程之间通信。您可以使用
wait()
notify()
来同步逻辑。例如

synchronized (lock) {
    lock.wait(); // Will block until lock.notify() is called on another thread.
}

// Somewhere else...
...
synchronized (lock) {
    lock.notify(); // Will wake up lock.wait()
}

类成员
Object lock=new Object()

在Java中,所有对象都实现这两个方法,显然,如果没有监视器,那么这两个方法是无用的。

此方法只能由作为此对象监视器所有者的线程调用
因此,我认为您必须确保有一个线程是对象上的监视器。

锁定是关于保护共享数据的

锁位于受保护的数据结构上。线程是访问数据结构的对象。锁位于数据结构对象上,以防止线程以不安全的方式访问数据结构

任何对象都可以用作内部锁(意思是与
synchronized
一起使用)。通过这种方式,您可以通过向访问共享数据的方法添加synchronized修饰符来保护对任何对象的访问

对用作锁的对象调用
wait
notify
方法。锁是一个共享通信点:

  • 当具有锁的线程调用其上的
    notifyAll
    时,等待该锁的其他线程将收到通知。当具有锁的线程调用其上的
    notify
    时,等待该锁的其中一个线程将收到通知

  • 当有锁的线程调用
    wait
    时,该线程释放锁并进入休眠状态,直到a)它收到通知,或b)它只是任意唤醒(“伪唤醒”);等待的线程仍然停留在调用中等待,直到由于这两个原因之一而被唤醒,然后线程必须重新获取锁,然后才能退出wait方法

请参见,Drop类是共享数据结构,使用生产者和消费者可运行程序的线程正在访问它。锁定Drop对象控制线程访问Drop对象数据的方式

线程在JVM实现中被用作锁,建议应用程序开发人员避免使用线程作为锁。例如,报告说:

此实现使用This.wait调用的循环,该循环以This.isAlive为条件。当线程终止时,调用this.notifyAll方法。建议应用程序不要在线程实例上使用wait、notify或notifyAll


Java5引入了显式锁,实现了
Java.util.concurrent.locks.Lock
。这些锁比隐式锁更灵活;有类似于等待和通知(等待和信号)的方法,但它们是基于条件的,而不是基于锁的。有多个条件可以只针对那些等待特定类型通知的线程。

您可以使用static
thread
class方法
sleep()
停止线程一段时间

如果要停止某些对象,需要在
syncronized
块内调用此方法

public class Main {

//some code

public void waitObject(Object object) throws InterruptedException {
    synchronized(object) {
        object.wait();
    }
}

public void notifyObject(Object object) throws InterruptedException {
    synchronized(object) {
        object.notify();
    }
}
}


另外,如果我错误理解了您的问题(英语不是我的母语)

当您在同步块中放置一些代码时,我很抱歉:

 sychronized(lock){...}
想要执行此块中的任何内容的线程首先会获得对象上的锁,并且一次只有一个线程可以执行锁定在同一对象上的代码。任何对象都可以用作锁,但在选择与作用域相关的对象时应小心。例如,当您有多个线程向帐户添加某些内容时,它们都有一些代码在块中负责,如:

sychronized(this){...}
然后不会发生同步,因为它们都锁定在不同的对象上。相反,您应该使用account对象作为锁。 现在考虑这些线程也有从帐户中退出的方法。在这种情况下,可能会出现一种情况,即希望提取某物的线程遇到一个空帐户。它应该等到有了钱,然后释放对其他线程的锁,以避免死锁。这就是wait和notify方法的用途。在本例中,遇到空帐户的线程将释放锁,并等待来自进行存款的某个线程的信号:

while(balance < amountToWithdraw){
    lock.wait();
}
正如您所看到的,方法wait和notify仅在同步块或方法中有意义

  • Wait和notify不仅仅是普通的方法或同步工具,更重要的是它们是Java中两个线程之间的通信机制。如果这个机制不能通过任何java关键字(如synchronized)使用,那么对象类就是使它们对每个对象都可用的正确位置。记住,synchronized和wait notify是两个不同的区域,不要混淆它们是相同的或相关的。Synchronized是在两个线程之间的通信机制wait和notify的同时,提供互斥性,保证Java类的线程安全性,比如争用条件
  • 锁在每个对象的基础上可用,这是在对象类而不是线程类中声明wait和notify的另一个原因
  • 在Java中,为了进入代码的关键部分,线程需要锁并等待锁,它们不知道哪个线程持有锁,而只是知道锁被某个线程持有,它们应该等待锁,而不是知道哪个线程在同步块中并要求它们释放锁。这个类比适用于等待和通知处于o状态
    while(balance < amountToWithdraw){
        lock.wait();
    }
    
    balance += amountToDeposit;
    lock.signallAll;
    
    import java.util.Vector;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    public class ProducerConsumerSolution {
    
        public static void main(String args[]) {
            Vector<Integer> sharedQueue = new Vector<Integer>();
            int size = 4;
            Thread prodThread = new Thread(new Producer(sharedQueue, size), "Producer");
            Thread consThread = new Thread(new Consumer(sharedQueue, size), "Consumer");
            prodThread.start();
            consThread.start();
        }
    }
    
    class Producer implements Runnable {
    
        private final Vector<Integer> sharedQueue;
        private final int SIZE;
    
        public Producer(Vector<Integer> sharedQueue, int size) {
            this.sharedQueue = sharedQueue;
            this.SIZE = size;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 7; i++) {
                System.out.println("Produced: " + i);
                try {
                    produce(i);
                } catch (InterruptedException ex) {
                    Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
                }
    
            }
        }
    
        private void produce(int i) throws InterruptedException {
    
            // wait if queue is full
            while (sharedQueue.size() == SIZE) {
                synchronized (sharedQueue) {
                    System.out.println("Queue is full " + Thread.currentThread().getName() + " is waiting , size: "
                            + sharedQueue.size());
    
                    sharedQueue.wait();
                }
            }
    
            // producing element and notify consumers
            synchronized (sharedQueue) {
                sharedQueue.add(i);
                sharedQueue.notifyAll();
            }
        }
    }
    
    class Consumer implements Runnable {
    
        private final Vector<Integer> sharedQueue;
        private final int SIZE;
    
        public Consumer(Vector<Integer> sharedQueue, int size) {
            this.sharedQueue = sharedQueue;
            this.SIZE = size;
        }
    
        @Override
        public void run() {
            while (true) {
                try {
                    System.out.println("Consumed: " + consume());
                    Thread.sleep(50);
                } catch (InterruptedException ex) {
                    Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
                }
    
            }
        }
    
        private int consume() throws InterruptedException {
            //wait if queue is empty
            while (sharedQueue.isEmpty()) {
                synchronized (sharedQueue) {
                    System.out.println("Queue is empty " + Thread.currentThread().getName()
                                        + " is waiting , size: " + sharedQueue.size());
    
                    sharedQueue.wait();
                }
            }
    
            //Otherwise consume element and notify waiting producer
            synchronized (sharedQueue) {
                sharedQueue.notifyAll();
                return (Integer) sharedQueue.remove(0);
            }
        }
    }