开发者

Exchanger appears to not exchange()

开发者 https://www.devze.com 2023-03-28 05:00 出处:网络
I have a pretty simple problem, in wich I try to exchange an object ( in this case an array of int) between two task : Producer and Consumer. The Producer class produces an array of int and than it tr

I have a pretty simple problem, in wich I try to exchange an object ( in this case an array of int) between two task : Producer and Consumer. The Producer class produces an array of int and than it tries to exchange it with the Consumer array ( which is an empty array) using an Exchanger object. But it seems that it doesn't work: when the Consumer tries to print the array, it gets nothing.

public class Producer implements Runnable{
private Exchanger<List<Integer>> exchanger;
private List<Integer> ints = new ArrayList<Integer>();

public Producer(Exchanger<List<Integer>> ex) {
    this.exchanger = ex;
}

public void run() {
    RandomGenerator.Integer gen = new RandomGenerator.Integer();
    try{
    while(!Thread.interrupted()) {
        for (int i = 0;i < Test.LIST_SIZE;i++) 
            ints.add(gen.next());
        exchanger.exchange(ints);
        //for(Integer x : ints) 
            //System.out.print(" " + x);
        //System.out.println();
    }
    }catch(InterruptedException e) {
        System.out.println("Producer interrupted");
    开发者_StackOverflow中文版}
}
}


public class Consumer implements Runnable {
private Exchanger<List<Integer>> exchanger;
private List<Integer> ints = new ArrayList<Integer>();

public Consumer(Exchanger<List<Integer>> ex) {
    this.exchanger = ex;
}

public void run() {
    try{
    while(!Thread.interrupted()) {
        exchanger.exchange(ints);
        System.out.println("Consumer:");
        for(Integer x : ints) {
            System.out.print(" " + x);
            ints.remove(x);
        }
        System.out.println();
    }
    } catch(InterruptedException e) {
        System.out.println("Consumer interrupted");
    }
}
}


public class Test {
public static final int LIST_SIZE = 10;

public static void main(String[] args) throws InterruptedException {
    ExecutorService exec = Executors.newCachedThreadPool();
    Exchanger<List<Integer>> exchanger = new Exchanger<List<Integer>>();
    exec.execute(new Producer(exchanger));
    exec.execute(new Consumer(exchanger));
    TimeUnit.MILLISECONDS.sleep(5);
    exec.shutdownNow();
}

If i uncomment the lines in Producer i see that the numbers generated are still there. So why does it not exchange the object?


The exchanger does not swap the references in place, but returns the exchanged object. So you should write something like:

List<Integer> received = exchanger.exchange(ints);
System.out.println("Consumer:");
for(Integer x : received) {
    System.out.print(" " + x);
        ...
}

BTW, I don't think exchangers are appropriate for producer/consumers...


The exchange isn't magical; the Exchanger object can't replace the object references itself. The documentation tells us that calling the function returns the object that was provided by the other thread, once the exchange point was reached, which is how we "receive" it. I haven't actually done any of this, but I assume you're meant to assign this result back; i.e. ints = exchanger.exchange(ints); in both classes.

0

精彩评论

暂无评论...
验证码 换一张
取 消