0

I have two Runnable classes, Reader and Writer.

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.util.concurrent.Exchanger;

public class Reader implements Runnable {
    private static final int THRESHHOLD = 1000;
    private final int START, STOP;
    private Exchanger<ByteBuffer> exch;
    private RandomAccessFile file;
    private ByteBuffer buffer;

    public Reader(Exchanger<ByteBuffer> ex, RandomAccessFile f, int start, int stop) {
        START = start;
        STOP = stop;
        exch = ex;
        file = f;
        buffer = ByteBuffer.allocate(THRESHHOLD);
        buffer.mark();
    }

    @Override
    public void run() {
        for(int i = START; i < STOP; i++)
            try {
                buffer.put((byte)file.read());
            } catch(IOException e) {
                e.printStackTrace();
            }
        try {
            exch.exchange(buffer);
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
    }
}



import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.util.concurrent.Exchanger;
import java.util.concurrent.locks.ReentrantLock;

public class Writer implements Runnable {
    private static final int THRESHHOLD = 1000;
    private final int START, STOP;
    private ReentrantLock lock;
    private Exchanger<ByteBuffer> exch;
    private RandomAccessFile file;
    private ByteBuffer buffer;

    public Writer(Exchanger<ByteBuffer> e, ReentrantLock l, RandomAccessFile f, int start, int stop) {
        lock = l;
        START = start;
        STOP = stop;
        exch = e;
        file = f;
    }

    @Override
    public void run() {
        try {
            buffer = exch.exchange(ByteBuffer.allocate(THRESHHOLD));
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
        lock.lock();
        for(int i = START; i < STOP; i++)
            try {
                file.write(buffer.get());
            } catch(IOException e) {
                e.printStackTrace();
            }
        lock.unlock();
    }

}

Both these threads use an Exchanger to exchange the same kind of data. How can I ensure that the exchange takes place between Reader and Writer threads only, and not between two threads of the smae kind?

JavaNewbie_M107
  • 2,007
  • 3
  • 21
  • 36

2 Answers2

0

Your question is little unclear. Since you are sharing the same exchanger instance between these reader and writer no other thread will be able to participate in this exchange.

Pragalathan M
  • 1,673
  • 1
  • 14
  • 19
0

If you are afraid that two threads "of the same kind" could invoke the exchange method of the same Exchanger instance (it's difficult to guess how it's possible from the example you brought, but you know your working mix better), then you can intercept (either by sub-classing or by delegation, whichever you like more) this method and check whether the combination of threads is right or wrong and what should done in every case. Here is an example by sub-classing, was tested only for a simplest case

public class ThreadStrictExchanger<V> extends Exchanger<V> {
    private Thread waitingThread; 

    @Override
    public V exchange(V x) throws InterruptedException {
        Thread currentThread = Thread.currentThread();
        if (waitingThread == null){
            waitingThread = currentThread;
        } else {
            checkThreads(waitingThread, currentThread);
            waitingThread = null;
        }
        return super.exchange(x);
    }

    private void checkThreads(Thread waitingThread, Thread currentThread) {
        //TODO add here your logic/change  
    }
}

You could compare the two threads by type or by name (use Thread.setName()/getName()). It's up to you what action to take if the combination of two threads in checkThreads method is wrong - either throw an exception or even return false to indicate that the actual invocation of Exchanger.exchange should be skipped (if it doesn't break the caller's logic).

Just replace Exchanger with your class on Reader and Writer ctors' invocations. Please note that another exchange method is not overridden but, if you need to, the logic will be the same.

igor.zh
  • 1,410
  • 15
  • 19