Вызов нескольких методов асинхронно и обновление объекта [дубликат]

Строка ошибки «Ссылка на объект, не установленная на экземпляр объекта.» указывает, что вы не назначили экземпляр объекта объектной ссылке, и все же вы получаете доступ к свойствам / методам этого объекта.

например: скажем, у вас есть класс под названием myClass и он содержит одно свойство prop1.

public Class myClass
{
   public int prop1 {get;set;}
}

Теперь вы получаете доступ к этому prop1 в каком-то другом классе, как показано ниже:

public class Demo
{
     public void testMethod()
     {
        myClass ref = null;
        ref.prop1 = 1;  //This line throws error
     }
}

выше строки выдает ошибку, потому что ссылка класса myClass объявлена, но не создана, или экземпляр объекта не назначается referecne этого класса.

Чтобы исправить это, вам нужно создать экземпляр (присвоить объект ссылке на этот класс).

public class Demo
{
     public void testMethod()
     {
        myClass ref = null;
        ref = new myClass();
        ref.prop1 = 1;  
     }
}
77
задан Felipe Hummel 3 December 2009 в 21:34
поделиться

9 ответов

Мне не нравится идея использования Reflection для этого. SecurityManager.

FutureTask является хорошим вариантом в качестве других опций из пакета java.util.concurrent. Это не просто опасно для его отсутствия в некоторых рефакторингах. Мой любимый для простых задач:

    Executors.newSingleThreadExecutor().submit(task);

немного короче, чем создание Thread (задача - Callable или Runnable)

17
ответ дан Buhake Sindi 24 August 2018 в 06:40
поделиться
  • 1
    Дело в том, что я просто хочу выполнить один вызов метода. Таким образом, мне пришлось бы изменить реализацию целевого класса. То, что я хотел, - это просто позвонить, не беспокоясь о том, чтобы навязать Runnable или Callable – Felipe Hummel 4 December 2009 в 03:44
  • 2
    то это не помогло бы много :( но обычно Я бы предпочел использовать Runnable или Callable вместо Reflection – Carlos Heuberger 4 December 2009 в 13:43
  • 3
    Просто короткая заметка: лучше отслеживать экземпляр ExecutorService, поэтому вы можете позвонить shutdown(), когда вам нужно. – Daniel Szalay 12 June 2012 в 10:36
  • 4
    Если вы это сделаете, не могли бы вы оказаться в закрытом ExecutorService, заставив вашу JVM отказаться от выключения? Я бы рекомендовал написать собственный метод, чтобы получить однопоточный, ограниченный по времени, ExecutorService. – djangofan 22 August 2017 в 17:32

Это действительно не связано, но если я должен асинхронно вызывать метод, например. matches (), я бы использовал:

private final static ExecutorService service = Executors.newFixedThreadPool(10);
public static Future<Boolean> matches(final String x, final String y) {
    return service.submit(new Callable<Boolean>() {

        @Override
        public Boolean call() throws Exception {
            return x.matches(y);
        }

    });
}

Тогда для вызова асинхронного метода я бы использовал:

String x = "somethingelse";
try {
    System.out.println("Matches: "+matches(x, "something").get());
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}

Я тестировал это, и он работает. Просто подумал, что это может помочь другим, если они просто пришли для «асинхронного метода».

2
ответ дан FlameBlazer 24 August 2018 в 06:40
поделиться

Это, вероятно, не настоящее решение, но теперь - в Java 8 - вы можете сделать этот код, по крайней мере, немного лучше, используя лямбда-выражение.

final String x = "somethingelse";
new Thread(() -> {
        x.matches("something");             
    }
).start();

И вы могли бы даже сделать это в одном line, все еще имея его довольно читаемым.

new Thread(() -> x.matches("something")).start();
2
ответ дан kcpr 24 August 2018 в 06:40
поделиться

Java 8 представил CompletableFuture, доступный в пакете java.util.concurrent.CompletableFuture, можно использовать для вызова асинхронного вызова:

CompletableFuture.runAsync(() -> {
    // method call or code to be asynch.
});
4
ответ дан Rahul Chauhan 24 August 2018 в 06:40
поделиться
  • 1
    CompletableFuture упоминался в другом ответе, но тот использовал целую цепочку supplyAsync(...). Это простая оболочка, которая идеально подходит для вопроса. – ndm13 5 February 2018 в 16:20

Возможно, вы захотите также рассмотреть класс java.util.concurrent.FutureTask.

Если вы используете Java 5 или более позднюю версию, FutureTask - это реализация «подстановочного асинхронного вычисления» под ключ. "

Есть еще более богатые асинхронные действия по планированию выполнения, доступные в пакете java.util.concurrent (например, ScheduledExecutorService), но FutureTask могут иметь все необходимые вам функции.

Я даже зашел так далеко, чтобы сказать, что уже не рекомендуется использовать первый образец кода, который вы дали в качестве примера с тех пор, как FutureTask стал доступен. (Предполагая, что вы находитесь на Java 5 или новее.)

26
ответ дан shadit 24 August 2018 в 06:40
поделиться
  • 1
    Дело в том, что я просто хочу выполнить один вызов метода. Таким образом, мне пришлось бы изменить реализацию целевого класса. То, что я хотел, - это просто позвонить, не беспокоясь о том, чтобы навязать Runnable или Callable – Felipe Hummel 4 December 2009 в 03:45
  • 2
    Я слышу тебя. Java пока не обладает первоклассными функциями, поэтому сейчас это самое современное. – shadit 4 December 2009 в 06:11
  • 3
    спасибо за «будущие» ключевые слова ... теперь я открываю учебники о них ... очень полезно. : D – gumuruh 7 June 2012 в 09:50
  • 4
    -1, насколько я могу судить, FutureTask сам по себе недостаточно для выполнения асинхронного запуска. Вам все равно нужно создать Thread или Executor для его запуска, как в примере с Карлосом. – MikeFHay 10 July 2013 в 11:21

Я только что обнаружил, что есть более чистый способ сделать ваш

new Thread(new Runnable() {
    public void run() {
        //Do whatever
    }
}).start();

(по крайней мере, в Java 8), вы можете использовать лямбда-выражение, чтобы сократить его до:

new Thread(() -> {
    //Do whatever
}).start();

Так же просто, как сделать функцию в JS!

105
ответ дан sm4 24 August 2018 в 06:40
поделиться
  • 1
    Ваш ответ помог моей проблеме - stackoverflow.com/questions/27009448/… . Немного сложно применить мою ситуацию, но в конечном итоге это удалось :) – Deckard 19 November 2014 в 07:56
  • 2
    Как звонить с параметрами? – yatanadam 29 December 2016 в 23:04
  • 3
    @yatanadam Это может ответить на ваш вопрос. Просто поместите вышеуказанный код внутри метода и как переменную, как обычно. Проверьте этот тестовый код , который я сделал для вас. – user3004449 12 April 2017 в 07:00
  • 4
    @eNnillaMS Должен ли быть остановлен поток после запуска? Он останавливается автоматически или сборщиком мусора ? – user3004449 12 April 2017 в 08:07
  • 5
    @ user3004449 Нить останавливается автоматически, однако вы также можете заставить ее. – Shawn S. 4 June 2018 в 21:25

Вы можете использовать синтаксис Java8 для CompletableFuture, таким образом вы можете выполнять дополнительные вычисления async на основе результата вызова функции async.

например:

 CompletableFuture.supplyAsync(this::findSomeData)
                     .thenApply(this:: intReturningMethod)
                     .thenAccept(this::notify);

Более подробную информацию можно найти в этой статье

6
ответ дан Tal Avissar 24 August 2018 в 06:40
поделиться

Для этого вы можете использовать Future-AsyncResult.

@Async
public Future<Page> findPage(String page) throws InterruptedException {
    System.out.println("Looking up " + page);
    Page results = restTemplate.getForObject("http://graph.facebook.com/" + page, Page.class);
    Thread.sleep(1000L);
    return new AsyncResult<Page>(results);
}

Ссылка: https://spring.io/guides/gs/async-method/

5
ответ дан user3177227 24 August 2018 в 06:40
поделиться

Вы можете использовать AsyncFunc из Cactoos :

boolean matches = new AsyncFunc(
  x -> x.matches("something")
).apply("The text").get();

Он будет выполнен в фоновом режиме, и результат будет доступен в get() как Future.

8
ответ дан yegor256 24 August 2018 в 06:40
поделиться
  • 1
    Обратите внимание, что этот подход заставит все вызовы сохранять асинхронные, что может или не может быть тем, что мы хотим. В случаях, когда только некоторые вызовы для данного метода должны быть сделаны async, могут использоваться другие подходы, предложенные на этой странице. – bmorin 22 October 2015 в 12:19
  • 2
    Могу ли я использовать его в веб-приложении (поскольку управление потоками там не рекомендуется)? – onlinenaman 5 July 2017 в 15:12
Другие вопросы по тегам:

Похожие вопросы: