Создайте метод, который возвращает значение из MySQL и выполняет запрос в потоке Async

Я разрабатываю плагин Minecraft с использованием Bukkit API.
Я хочу проверить, зарегистрирован ли игрок с помощью специального статического метода.

static boolean isRegistered(String username)

Этот метод должен выполнять запрос MySQL (SELECT) и соответственно возвращать истину / ложь. Чтобы избежать задержки основного потока, я хотел бы выполнить этот запрос в потоке Async внутри этого метода. Bukkit реализует Runnable под названием BukkitRunnable, который используется следующим образом:

static boolean isRegistered(String username) {
  new BukkitRunnable() {
    /* MySQL code here */
  }.runTaskAsynchronously(this);
}

поэтому извне этого метода мы не знаем, что этот метод делает внутри. Мы просто хотим получить истину, если игрок зарегистрирован, и нам все равно, как это делает этот метод.

Теперь предположим, что этот метод является частью API, который предоставляет некоторые методы, такие как isRegistered, поэтому мы не знаем, откуда он будет вызван.

Мой вопрос: как я могу правильно вернуть true / false из моего isRegistered метода, не заставляя основной поток ждать до завершения запроса?


person Mára Toner    schedule 26.08.2016    source источник
comment
Вы не можете return a boolean и запускать задачу асинхронно - это ерунда - вы не можете съесть свой торт и получить его тоже. Вам либо необходимо иметь тип возврата Future<Boolean> и запускать async , либо иметь тип возврата boolean и запускать синхронизацию. Если исполняемый код ожидает boolean, он будет ждать, пока не получит его (или _6 _) ...   -  person Boris the Spider    schedule 26.08.2016
comment
Ну, если бы у меня было два торта, я бы его съел, а один остался. Но серьезно, вы можете опубликовать пример с Future ‹›? Никогда не слышал об этом, все люди из Bukkit говорили что-то о обратных вызовах ... но я все еще новичок в Java.   -  person Mára Toner    schedule 26.08.2016


Ответы (2)


Вы можете попробовать что-то подобное, но на самом деле это не рекомендуется:

public boolean isRegistered(final String name) {
    ExecutorService executor = Executors.newSingleThreadExecutor();
    Future<Boolean> result = executor.submit(new Callable<Boolean>() {

        @Override
        public synchronized Boolean call() throws Exception {
            // DO SOMETHING
            return true;
        }
    });
    try {
        return result.get();
    } catch (Exception e) {
        return false;
    } finally {
        executor.shutdown();
    }
}
person Xephi    schedule 29.10.2016
comment
Я считаю, что это решение не может работать асинхронно. Потому что вы ждете ответа на result.get (). Он не хочет ждать, пока это закончится. - person Melikşah Şimşek; 30.10.2016

Вы можете создать интерфейс для завершения асинхронной задачи. Я написал для этого фрагмент кода.

ResponseListener.java

interface IResponseListener {
    void response(ResponseEvent event);
}

ResponseEvent.java

public class ResponseEvent {

   private Object response;

   @SuppressWarnings("unchecked")
   public <T> T getResponse() {
       return (T)response;
   }

   public <T> void setResponse(T response) {
       this.response = response;
   }
}

Использование:

    static void isRegistered(String username, IResponseListener listener) {
       new BukkitRunnable() {
            /* MySQL code here */
            Boolean isRegistered = userRepository.isRegistered();
            ResponseEvent event = new ResponseEvent();
            event.setResponse(isRegistered);
            listener.response(event);
       }.runTaskAsynchronously(this);
    }

    isRegistered("userName", new IResponseListener() {
        public void response(ResponseEvent event) {
            Boolean response = event.getResponse();
            if(response) {
                 //Do registered user stuff
            } else {
                 //Do unregistered user stuff
            }
        } 
    });

Обратите внимание, что вы получите ClassCastException, если ваш тип отличается от того, который вы ожидаете.

person Melikşah Şimşek    schedule 29.10.2016