簡體   English   中英

對如何在Java中使用交換器感到困惑

[英]Confused about how to use exchanger in java

與基本上每個交換器任務一樣,我讓生產者填充一個空的buffer2,由消費者清除一個完整的buffer1,當每個線程完成后,他們應該交換各自的緩沖區。

我真的不確定在哪里以及如何申請交易所。 我將readyconsumer和readyproducer定義為布爾值,以便第三個線程可以檢查是否在兩個都成立時就交換緩沖區。 這應該可以解決我用兩個線程執行的問題,其中程序在wait()處被兩個線程卡住了(不幸的是,現在仍然如此)。

這是當前代碼的樣子。 誰能幫助我在哪個班級以及在代碼的什么時候進行交流? 提前非常感謝您!

    class Buffer {
        static boolean readyconsumer, readyproducer = false;

        volatile int count; // number of put actions
        static int max = 10;

        Buffer() {
        count = 0;
        }

        public synchronized void put() {
            if (count == max) {
                readyproducer = true;
                System.out.println("          wait ");
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
            count++;
            System.out.println("put " + count);
            notifyAll();
        }

        public synchronized void get() {
            if (count == 0) {
                readyconsumer = true;
                System.out.println("          wait");
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
            count--;
            System.out.println("get " + count);
            notifyAll();
        }
    }


class CheckandSwitch extends ProdCon {
    public void run() {

        while (true) {

            if (Buffer.readyconsumer && Buffer.readyproducer) {
                try {
                    ProdCon.buffer2 = exchanger.exchange(ProdCon.buffer1);
                    ProdCon.buffer1 = exchanger.exchange(ProdCon.buffer2);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    }
                Buffer.readyconsumer = false;
                Buffer.readyproducer = false;
                buffer1.count = 0;
                buffer2.count = 10;
                notifyAll();
            }

        }
    }

}

class Consumer extends ProdCon {
    static Buffer buffer;

    Consumer(Buffer b) {
        super();
        buffer = b;
        b.count = 10;
    }

    public void run() {
        while (true) {
            consume();
            buffer.get();
        }
    }

    private void consume() {
        System.out.println("consume");
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
        }
    }
}

class Producer extends ProdCon {
    static Buffer buffer;

    Producer(Buffer b) {
        super();
        buffer = b;
        b.count = 0;
    }

    public void run() {
        while (true) {
            produce();
            buffer.put();
        }
    }

    private void produce() {
        System.out.println("produce ");
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
        }
    }
}

import java.util.concurrent.*;

public class ProdCon extends Thread {
    static Exchanger<Buffer> exchanger = new Exchanger<Buffer>();
    static Buffer buffer1, buffer2 = null;

    public static void main(String[] args) {

        buffer1 = new Buffer();
        buffer2 = new Buffer();
        new Consumer(buffer1).start();
        new Producer(buffer2).start();
        new CheckandSwitch().start();

    }
}

您可以使用Exchanger

這是將Javadoc中的代碼調整為一個工作示例。

class DataBuffer<T> {

    T data = null;

    public boolean isFull() {
        return data != null;
    }

    public boolean isEmpty() {
        return data == null;
    }

    public T get() {
        T d = data;
        data = null;
        return d;
    }

    public void put(T data) {
        this.data = data;
    }
}

class FillAndEmpty {

    Exchanger<DataBuffer<Integer>> exchanger = new Exchanger<>();
    DataBuffer<Integer> initialEmptyBuffer = new DataBuffer<>();
    DataBuffer<Integer> initialFullBuffer = new DataBuffer<>();
    int countDown = 10;

    class FillingLoop implements Runnable {

        @Override
        public void run() {
            DataBuffer currentBuffer = initialEmptyBuffer;
            try {
                while (currentBuffer != null && countDown > 0) {
                    addToBuffer(currentBuffer);
                    if (currentBuffer.isFull()) {
                        currentBuffer = exchanger.exchange(currentBuffer);
                    }
                }
            } catch (InterruptedException ex) {
            }
        }

        private void addToBuffer(DataBuffer<Integer> currentBuffer) {
            currentBuffer.put(countDown--);
        }
    }

    class EmptyingLoop implements Runnable {

        @Override
        public void run() {
            DataBuffer<Integer> currentBuffer = initialFullBuffer;
            try {
                while (currentBuffer != null) {
                    takeFromBuffer(currentBuffer);
                    if (currentBuffer.isEmpty()) {
                        currentBuffer = exchanger.exchange(currentBuffer);
                    }
                }
            } catch (InterruptedException ex) {
            }
        }

        private void takeFromBuffer(DataBuffer<Integer> currentBuffer) {
            System.out.println(currentBuffer.get());
        }
    }

    void start() {
        new Thread(new FillingLoop()).start();
        new Thread(new EmptyingLoop()).start();
    }
}

public void test() {
    System.out.println("Hello");
    new FillAndEmpty().start();
}

暫無
暫無

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

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