Я хочу получить возвращаемое значение из функции объекта после 5 секунд в Java - PullRequest
0 голосов
/ 06 ноября 2019

Я делаю основную карточную игру, в которую пользователь может играть с компьютером или с компьютером в Java. Я хочу взять выборку как случайное число из функции выбора в классе Computer Player, которая расширяет мой класс Player. Но я хочу получить ответ через 5 секунд после вызова функции выбора. Также я должен получить ответ из функции выбора в классе Human Player со слушателем мыши.

Я создаю таймер официанта, который запускается при вызове моей функции выбора.

Timer waiter = new Timer(5000,this);
boolean is_waiting;

public int select_cart() {
        waiter.start();
        is_waiting = true;
        Random r = new Random();
        int random = r.nextInt(getCartNumber()) + 1;
        int selection = random;
        while(is_waiting){
            System.out.println("Computer is selecting...");
        }
        return selection;
    }

@Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == waiter){
            is_waiting = false;
            waiter.stop();
        }
    }

Я ожидаю, что функция select_cartвернуть значение через 5 секунд, но этот код вывести «Компьютер выбирает ...» на консоль в бесконечном цикле.

1 Ответ

1 голос
/ 07 ноября 2019

Если select_cart вызван из потока диспетчеризации событий

Затем вам нужно изменить свой подход, так как while-loop блокирует поток диспетчеризации событий, то есть Timer 's *Метод 1006 * никогда не будет вызван.

В этом случае лучшим подходом будет позволить методу actionPerformed фактически вызвать результат, но для его создания вам понадобится шаблон наблюдателя. работа

Начните с определения обратного вызова interface, что-то вроде ...

public interface CartSelection {
    public void cartSelection(int value);
}

Затем вам нужно изменить код, чтобы использовать этот обратный вызов и переместить основные функции на actionPerformed, например ...

Timer waiter = new Timer(5000,this);
CartSelection callback;

public void select_cart(CartSelection callback) {
    this.callback = callback;
    waiter.start();
}

@Override
public void actionPerformed(ActionEvent e) {
    if(e.getSource() == waiter){
        waiter.stop();
        Random r = new Random();
        int random = r.nextInt(getCartNumber()) + 1;
        int selection = random;
        callback(selection)
    }
}

Тогда вы можете назвать select_cart что-то вроде ...

select_cart(new CartSelection() {
    @Override
    public void cartSelection(int value) {
        // Carry on...
    }
});

в качестве примера.

Есликорзина была заполнена каким-то другим процессом, тогда вы могли бы рассмотреть возможность использования других подходов, таких как Lock объектов, чтобы «дождаться» завершения процесса заполнения.

Точно так же вы могли быиспользуйте SwingWorker, чтобы заполнить корзину, и когда она будет завершена, publish результаты, которые будут использованы с помощью другого механизма.

Если select_cart вызывается из другого потока

Теперь, если вы вызываете select_cart из другого потока (другогозатем EDT), тогда вам вообще не нужен Timer, и вы могли бы просто сделать ...

public int select_cart() {
    Random r = new Random();
    int random = r.nextInt(getCartNumber()) + 1;
    int selection = random;
    try {
        Thread.sleep(5000);
    } catch (InterruptedException ex) {
    }
    return selection;
}
...