交换器似乎没有交换()
我有一个非常简单的问题,我尝试在两个任务:生产者和消费者之间交换一个对象(在本例中是一个 int 数组)。 Producer 类生成一个 int 数组,然后尝试使用 Exchanger 对象与 Consumer 数组(这是一个空数组)进行交换。但它似乎不起作用:当消费者尝试打印数组时,它什么也得不到。
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();
}
如果我取消注释 Producer 中的行,我会看到生成的数字仍然存在。那么为什么它不交换对象呢?
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");
}
}
}
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
交换器不会就地交换引用,而是返回交换的对象。所以你应该写这样的内容:
顺便说一句,我认为交换器不适合生产者/消费者......
The exchanger does not swap the references in place, but returns the exchanged object. So you should write something like:
BTW, I don't think exchangers are appropriate for producer/consumers...
这种交换并不神奇; Exchanger 对象无法替换对象引用本身。文档告诉我们,一旦到达交换点,调用该函数就会返回另一个线程提供的对象,这就是我们“接收”它的方式。我实际上没有做过任何这些,但我认为你应该将这个结果分配回来;即两个类中的ints = Exchange.exchange(ints);。
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.