Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.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_Producer Consumer - Fatal编程技术网

在Java中使用wait()和notify()的生产者-消费者程序

在Java中使用wait()和notify()的生产者-消费者程序,java,multithreading,producer-consumer,Java,Multithreading,Producer Consumer,我使用低级同步和wait()和notify()在Java中处理典型的生产者-消费者问题。我知道有更好的实现使用java.util.concurrent包中的结构,但我的问题是围绕低级别实现: private static ArrayList<Integer> list = new ArrayList<Integer>(); static Object obj = new Object(); public static void producer() t

我使用低级同步和wait()和notify()在Java中处理典型的生产者-消费者问题。我知道有更好的实现使用java.util.concurrent包中的结构,但我的问题是围绕低级别实现:

private static ArrayList<Integer> list = new ArrayList<Integer>();

    static Object obj = new Object();

    public static void producer() throws InterruptedException {
        synchronized (obj) {
            while (true) {
                if (list.size() == 10) {
                    System.out.println("Queue full.. Waiting to Add");
                    obj.wait();
                } else {
                    int value = new Random().nextInt(100);
                    if (value <= 10) {
                        Thread.sleep(200);
                        System.out.println("The element added was : " + value);
                        list.add(value);
                        obj.notify();
                    }
                }
            }
        }

    }

    public static void consumer() throws InterruptedException {
        synchronized (obj) {
            while (true) {
                Thread.sleep(500);
                if (list.size() == 0) {
                    System.out.println("Queue is empty...Waiting to remove");
                    obj.wait();
                } else {
                    System.out.println("The element removed was : "
                            + list.remove(0));
                    obj.notify();
                }
            }
        }

    }
编辑:以下是更正的代码:

private static ArrayList<Integer> list = new ArrayList<Integer>();
    private static Object obj = new Object();

    public static void producer() throws InterruptedException {
        while (true) {
            Thread.sleep(500);
            if (list.size() == 10) {
                System.out.println("Waiting to add");
                synchronized (obj) {
                    obj.wait();
                }
            }
            synchronized (obj) {
                int value = new Random().nextInt(10);
                list.add(value);
                System.out.println("Added to list: " + value);
                obj.notify();
            }
        }
    }

    public static void consumer() throws InterruptedException {
        while (true) {
            Thread.sleep(500);
            if (list.size() == 0) {
                System.out.println("Waiting to remove");
                synchronized (obj) {
                    obj.wait();
                }
            }
            synchronized (obj) {
                int removed = list.remove(0);
                System.out.println("Removed from list: " + removed);
                obj.notify();
            }
        }
    }
private static ArrayList list=new ArrayList();
私有静态对象obj=新对象();
public static void producer()引发InterruptedException{
while(true){
睡眠(500);
if(list.size()==10){
System.out.println(“等待添加”);
同步(obj){
obj.wait();
}
}
同步(obj){
int value=new Random().nextInt(10);
列表。添加(值);
System.out.println(“添加到列表:“+值”);
obj.notify();
}
}
}
public static void consumer()引发InterruptedException{
while(true){
睡眠(500);
if(list.size()==0){
System.out.println(“等待删除”);
同步(obj){
obj.wait();
}
}
同步(obj){
int removed=list.remove(0);
System.out.println(“从列表中删除:”+删除);
obj.notify();
}
}
}

不能使用同一对象在同步块中运行两个线程。当一个方法正在运行时,另一个方法无法运行,直到另一个线程调用
wait
method


要解决此问题,您只需将
添加
删除
放在同步块中即可。有关更多信息,请参阅。

生产者和消费者问题是多进程同步问题的经典示例。这描述了共享公共资源的两个进程,生产者和消费者,缓冲区。生产者作业是生成数据并将其放入缓冲区,消费者作业是消费生成的数据并从缓冲区中删除

生产者必须确保在缓冲区已满时不添加任何元素,它应该调用
wait()
,直到消费者使用一些数据并
通知生产者线程,消费者必须确保它不应该在缓冲区已空时尝试从缓冲区中删除项目,它应该调用
wait()
只需等待生产者生成数据并将其添加到缓冲区,然后使用
notify
notifyAll
通知消费者即可

这个问题可以通过使用
BlockingQueue
接口来解决,该接口管理生产者和消费者自己的实现

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * To change this license header, choose License Headers in Project `Properties`.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author sakshi
 */
public class ThreadProducer {

    static List<Integer> list = new ArrayList<Integer>();

    static class Producer implements Runnable {

        List<Integer> list;

        public Producer(List<Integer> list) {
            this.list = list;
        }

        @Override
        public void run() {
            synchronized (list) {
                for (int i = 0; i < 10; i++) {
                    if (list.size() >= 1) {
                        try {
                            System.out.println("producer is waiting ");
                            list.wait();
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }

                    System.out.println("produce=" + i);
                    list.add(i);
                    list.notifyAll();
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }

            }

            //To change body of generated methods, choose Tools | Templates.
        }

    }

    static class Consumer implements Runnable {

        List<Integer> list;

        public Consumer(List<Integer> list) {
            this.list = list;
        }

        @Override
        public void run() {

            synchronized (list) {
                for (int i = 0; i < 10; i++) {

                    while (list.isEmpty()) {
                        System.out.println("Consumer is waiting");
                        try {
                            list.wait();
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();;
                        }

                    }

                    int k = list.remove(0);
                    System.out.println("consume=" + k);
                    list.notifyAll();
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }

                }

            }
        }

    }

    public static void main(String[] args) {
        Thread producer = new Thread(new Producer(list));
        Thread consumer = new Thread(new Consumer(list));
        producer.start();
        consumer.start();

    }
}
不要使用
list.size()==10
,而是可以选中
list.size==1

对于生产商而言,一方等待另一方,直到消费者消费。请参阅本课程参考资料{

private final int capacity = 2;
public static int value = 0;

LinkedList < Integer > list;

Resources() {
    list = new LinkedList < > ();
}

void consume() throws InterruptedException {
    while (true) {
        synchronized(this) {
            while (list.size() == 0) {
                wait();
            }
            int val = list.removeFirst();
            System.out.println("Value consumed:" + val);
            notify();
            //Thread.sleep(1000);
        }
    }
}

void produce() throws InterruptedException {
    while (true) {
        synchronized(this) {
            while (list.size() == capacity) {
                wait();
            }
            System.out.println("Value produced:" + value);
            list.add(value++);
            notify();
            Thread.sleep(1000);

        }
    }
}
}

公共类ProducerConsumerExample{

public static void main(String[] args) {
    try {
        Resources rs = new Resources();
        MyThread5 m1 = new MyThread5(rs, "Producer");
        MyThread5 m2 = new MyThread5(rs, "Consumer");
        m1.start();
        m2.start();

        m1.join();
        m2.join();
    } catch (InterruptedException ex) {
        Logger.getLogger(ProducerConsumerExample.class.getName()).log(Level.SEVERE, null, ex);
    }

}

}

为什么要使用
if(list.size()==10)
?@SotiriosDelimanolis只是为了模拟队列的最大大小/深度,您看到它是如何应用的了吗?唯一的问题是,生产者继续一次生成消息,直到消息的最大值(直到列表的大小为10),消费者一次消费全部10条消息。?是的。如果达到列表的最大大小,线程将等待
(obj.wait())
。但是在
obj.notify()
之后,它应该在
中再次继续,而(true)
循环生成
notify()
不会释放相应对象的锁。这是一个很好的示例。但最好在Producer中使用while循环on条件,因为存在虚假的唤醒可能性。不幸的是,链接已经死了。
private final int capacity = 2;
public static int value = 0;

LinkedList < Integer > list;

Resources() {
    list = new LinkedList < > ();
}

void consume() throws InterruptedException {
    while (true) {
        synchronized(this) {
            while (list.size() == 0) {
                wait();
            }
            int val = list.removeFirst();
            System.out.println("Value consumed:" + val);
            notify();
            //Thread.sleep(1000);
        }
    }
}

void produce() throws InterruptedException {
    while (true) {
        synchronized(this) {
            while (list.size() == capacity) {
                wait();
            }
            System.out.println("Value produced:" + value);
            list.add(value++);
            notify();
            Thread.sleep(1000);

        }
    }
}
Resources rs;
String name;

public String getNames() {
    return name;
}

public MyThread5(Resources rs, String name) {
    this.rs = rs;
    this.name = name;
}

@Override
public void run() {
    if (this.getNames().equals("Producer")) {
        try {
            this.rs.produce();
        } catch (InterruptedException ex) {
            Logger.getLogger(MyThread5.class.getName()).log(Level.SEVERE, null, ex);
        }
    } else {
        try {
            this.rs.consume();
        } catch (InterruptedException ex) {
            Logger.getLogger(MyThread5.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
public static void main(String[] args) {
    try {
        Resources rs = new Resources();
        MyThread5 m1 = new MyThread5(rs, "Producer");
        MyThread5 m2 = new MyThread5(rs, "Consumer");
        m1.start();
        m2.start();

        m1.join();
        m2.join();
    } catch (InterruptedException ex) {
        Logger.getLogger(ProducerConsumerExample.class.getName()).log(Level.SEVERE, null, ex);
    }

}