簡體   English   中英

嘗試使用多線程解決Java中的消費者生產者

[英]Trying to solve consumer-producer in java with multithreading

我正在嘗試使用Java中的線程解決生產者使用者問題,但是代碼不會並行/並行運行。 生產者總是在消費者開始消費之前完全填滿緩沖區,我不知道為什么。 重點是嘗試僅使用同步塊,wait()和notify()來完成此操作。

主要:

    String [] data = {"Fisk", "Katt", "Hund", "Sau", "Fugl", "Elg", "Tiger", 
               "Kameleon", "Isbjørn", "Puma"};
    ProducerConsumer pc = new ProducerConsumer(5);
    Thread[] thrds = new Thread[2];
    thrds[0] = new Thread(new MyThread1(pc, data)); // producer
    thrds[1] = new Thread(new MyThread2(pc)); // consumer
    thrds[0].start();
    thrds[1].start();
    for(int i = 0; i < 2; i++) { // wait for all threads to die
        try { 
            thrds[i].join(); 
        } 
        catch (InterruptedException ie) {}
    }
    System.exit(0);

ProducerConsumer.java:

import java.util.LinkedList;
import java.util.Queue;

public class ProducerConsumer implements Runnable {
    private int bufferSize;
    private Queue<String> buffer;

public ProducerConsumer(int size) {

    bufferSize = size;
    buffer = new LinkedList<String>();
}

public void produce(String item) throws InterruptedException {
        synchronized(buffer) {
            while (buffer.size() >= bufferSize) {
                try {
                    System.out.println("Full buffer. Waiting for consumer...");
                    buffer.wait();
                }catch (Exception e) {}
            }
            buffer.add(item);
            System.out.println("Producer is putting " + item + " in the buffer");
            buffer.notify();
        }   
}

public void consume() throws InterruptedException {
    synchronized (buffer) {
        while (buffer.size() == 0) {
            try {
                System.out.println("Empty buffer. Waiting for production...");
                buffer.wait();
            }catch (Exception e) {}
        }
        System.out.println("Consumer is consuming " +  buffer.remove() + ".");
        buffer.notify();
    }
}

@Override
public void run() {
}

}

MyThread1:

/*
 * PRODUCER - Thread
 */
public class MyThread1 implements Runnable {

private String [] data;
private ProducerConsumer pc;

public MyThread1(ProducerConsumer pc, String [] data) {
    this.pc = pc;
    this.data = data;
}
@Override
public void run() {
    for (int i = 0; i < data.length; i++) {
        try {
            pc.produce(data[i]);
        } catch (InterruptedException ex) {}
    }
}

}

MyThread2:

//消費-線程

public class MyThread2 implements Runnable{

private ProducerConsumer pc;

public MyThread2(ProducerConsumer pc) {
    this.pc = pc;
}

//Run consume
@Override
public void run() {
    while (true) {
        try {
            pc.consume();
            Thread.sleep(2);
        }
        catch(InterruptedException e) {}

    }

}
}

在最近的機器上,這樣的隊列很短,除非您將兩者都放慢一點,否則您將永遠看不到實際的多線程效果,例如在這種情況下,生產者和使用者輪流使用。 您只會減慢消費者的速度。 而不是使用短數組,而是將一百萬個Integers放在隊列中,看看會發生什么。

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class ProduserConsumerDemo {

    public static void main(String[] args) {
        List<Integer> list = new CopyOnWriteArrayList<>();
        int size = 5;
        Producer producer = new Producer(list, size);
        Consumer consumer = new Consumer(list);
        Thread t1 = new Thread(producer, "Producer");
        Thread t2 = new Thread(consumer, "Consumer");
        t1.start();
        t2.start();
    }
}

class Producer implements Runnable {
    private final List<Integer> list;
    private final int size;

    public Producer(List<Integer> list, final int size) {
        this.list = list;
        this.size = size;
    }

    public void run() {
        try {
            produce();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void produce() throws InterruptedException {
        int i = 0;
        while (i >= 0) {
            synchronized (list) {
                while (list.size() == size) {
                    System.out.println(
                            "List is full." + Thread.currentThread().getName() + " is waiting. Size:" + list.size());
                    list.wait();
                }
                System.out.println("Produce :" + i);
                list.add(i++);
                Thread.sleep(50);
                list.notify();
            }
        }
    }
}

class Consumer implements Runnable {
    private final List<Integer> list;

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

    public void run() {
        try {
            consume();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void consume() throws InterruptedException {
        while (true) {
            synchronized (list) {
                while (list.isEmpty()) {
                    System.out.println(
                            "List is empty. " + Thread.currentThread().getName() + " is waiting. Size:" + list.size());
                    list.wait();
                }
                System.out.println("Consumed item:" + list.remove(0));
                Thread.sleep(50);
                list.notify();
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM