0

This method functions as intended, in that it only gets one object at a time from the server at a time, handles that object, and then gets another. However, it seems that I need to, seemingly, turn it inside out, probably with Producer-Consumer:

    public void inputOutput() throws IOException, ClassNotFoundException {
        Socket socket = new Socket(server, portNumber);
        boolean eof = false;
        Title title = null;
        State state = State.undefined;
        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
                ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream())) {
            do {
                try {
                    title = (Title) objectInputStream.readObject();
                    log.info(title.toString());
                    do {
                        state = State.undefined;
                        try {
                            c.printf("enter the state for record:");
                            state = State.valueOf(c.readLine());
                        } catch (java.lang.IllegalArgumentException iae) {
                            log.warning(Arrays.deepToString(State.values()));
                        }
                    } while (state == State.undefined);
                    title.setState(state);
                    title.setTitle("modified from client");
                    objectOutputStream.writeObject(title);
                } catch (java.io.EOFException eofe) {
                    eof = true;
                }
            } while (!eof);
        }
    }

The "flow", of handling one object, and then sending it back, and then requesting another, is exactly what I want to replicate:

package net.bounceme.dur.client;

import java.util.concurrent.BlockingQueue;

public class Producer implements Runnable {

    private final BlockingQueue<Message> queue;

    public Producer(BlockingQueue<Message> q) {
        this.queue = q;
    }

    @Override
    public void run() {
        //produce messages
        for (int i = 0; i < 100; i++) {
            Message msg = new Message("" + i);
            try {
                Thread.sleep(i);
                queue.put(msg);
                System.out.println("Produced " + msg.getMsg());
            } catch (InterruptedException e) {
            }
        }
        //adding exit message
        Message msg = new Message("exit");
        try {
            queue.put(msg);
        } catch (InterruptedException e) {
        }
    }

}

Would the Producer just handle getting objects from the socket connection via objectInputStream.readObject();, for example?

If so, how do I slow down the Producer (which, from a certain perspective, is also a consumer) so that it only "produces" one object at a time, waits to be notified, and then, only when notified, goes back to the stream for another object.

From within the context of the client, this is a producer, but, from a wider view, I suppose it's also a consumer.

How does the producer receive a semaphore, or other notification, to then "produce" another object?

Because Producer implements Runnable, I cannot pass parameters into run. Could, perhaps, the ProducerConsumerService driver pause the thread? That seems error-prone, at the least.

code borrowed from:

http://www.journaldev.com/1034/java-blockingqueue-example-implementing-producer-consumer-problem

Explicit answers not required -- I'm probably just misunderstanding how to use a BlockingQueue with Sockets. At present, I want to leave the server unchanged, so that its response/request "flow" of sending an object, and then waiting for a response, stays like that.

Thufir
  • 8,216
  • 28
  • 125
  • 273

1 Answers1

1

One solution is to use a size 1 ArrayBlockingQueue. The producer can only put one object at a time in there, and wait until the consumer removes it.

So the pseudocode would be something like...

// Producer thread (produces serverside data)
obj = readObjFromServer();
sharedQueue.put(obj);  // Blocks if there is already an object waiting

// Consumer thread
obj = sharedQueue.take(); // Blocks until data available
handleData(obj);
Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • I like that. So, until the consumer removes the object, the producer (above) just "hangs"? sounds good! :) – Thufir Jul 09 '14 at 11:23
  • 1
    Yup, the operations block if the queue is full (for inserting), or empty (for retrieving). – Kayaman Jul 09 '14 at 11:25