Java Exchanger 示例不起作用

问题描述 投票:0回答:2

我有以下代码。该代码创建两个分别带有消息“Hello”和“World”的可运行对象。 我希望这能与“World”交换“Hello”,但它不起作用。代码被卡住并且交换永远不会发生

将代码更改如下。现在可以用了

public class ExchangerExample {

public static void main(String[] args) {
    Exchanger<String> exchanger = new Exchanger();

    new Thread(() -> {
        try {
            String message = "Hello";
            Object previous = message;
            message = exchanger.exchange(message);
            System.out.println(previous + " is changed to " + message);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();

    new Thread(() -> {
        try {
            String message = "World";
            Object previous = message;
            message = exchanger.exchange(message);
            System.out.println(previous + " is changed to " + message);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
}

}

java concurrency java.util.concurrent
2个回答
0
投票

首先,这对于编写这样的程序来说不是一个好的设计,看起来像意大利面条代码,首先编写一个

ExchangerRunnable
类:

public class ExchangerRunnable implements Runnable{

    Exchanger exchanger = null;
    Object    object    = null;

    public ExchangerRunnable(Exchanger exchanger, Object object) {
        this.exchanger = exchanger;
        this.object = object;
    }

    public void run() {
        try {
            Object previous = this.object;

            this.object = this.exchanger.exchange(this.object);

            System.out.println(
                    Thread.currentThread().getName() +
                    " exchanged " + previous + " for " + this.object
            );
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

然后你就可以按照下面的方式使用它:

Exchanger exchanger = new Exchanger();

ExchangerRunnable exchangerRunnable1 =
        new ExchangerRunnable(exchanger, "Hello");

ExchangerRunnable exchangerRunnable2 =
        new ExchangerRunnable(exchanger, "World");

new Thread(exchangerRunnable1).start();
new Thread(exchangerRunnable2).start();

输出将是:

Thread-0 exchanged Hello for World
Thread-1 exchanged World for Hello

有什么问题吗?


0
投票

在此测验中,您的 main 不会等待后台线程,并且可以在交换之前中断它们。添加此:

thread1.join();
thread2.join();
© www.soinside.com 2019 - 2024. All rights reserved.