简体   繁体   English

交换器似乎不交换()

[英]Exchanger appears to not exchange()

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.我有一个非常简单的问题,我尝试在两个任务之间交换 object(在这种情况下是一个 int 数组):生产者和消费者。 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. Producer class 生成一个 int 数组,然后尝试使用 Exchanger object 与 Consumer 数组(这是一个空数组)交换它。 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");
    }
}
}


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.如果我取消注释 Producer 中的行,我会看到生成的数字仍然存在。 So why does it not exchange the object?那么为什么不换object呢?

The exchanger does not swap the references in place, but returns the exchanged object.交换器不会就地交换引用,而是返回交换的 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.交换器 object 不能替换 object 引用本身。 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.文档告诉我们,一旦到达交换点,调用 function 将返回另一个线程提供的 object,这就是我们“接收”它的方式。 I haven't actually done any of this, but I assume you're meant to assign this result back;我实际上并没有做任何这些,但我假设你打算把这个结果分配回去; ie ints = exchanger.exchange(ints);ints = exchanger.exchange(ints); in both classes.在两个班级。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM