В последнее время я смотрел горутины Go и подумал, что было бы неплохо иметь что-то подобное в Java. Насколько я искал, обычный способ распараллеливания вызова метода - это сделать что-то вроде:
final String x = "somethingelse";
new Thread(new Runnable() {
public void run() {
x.matches("something");
}
}).start();
Это не очень элегантно. Есть ли лучший способ сделать это? Мне нужно было такое решение в проекте, поэтому я решил реализовать свой собственный класс-оболочку вокруг вызова асинхронного метода.
Я опубликовал свой класс-оболочку в J-Go . Но я не знаю, хорошее ли это решение. Использование простое:
SampleClass obj = ...
FutureResult<Integer> res = ...
Go go = new Go(obj);
go.callLater(res, "intReturningMethod", 10); //10 is a Integer method parameter
//... Do something else
//...
System.out.println("Result: "+res.get()); //Blocks until intReturningMethod returns
или менее подробный:
Go.with(obj).callLater("myRandomMethod");
//... Go away
if (Go.lastResult().isReady()) //Blocks until myRandomMethod has ended
System.out.println("Method is finished!");
Внутри я использую класс, реализующий Runnable, и выполняю некоторую работу по отражению, чтобы получить правильный объект метода и вызвать его.
Я хочу получить некоторое мнение о моей крошечной библиотеке и о том, как делать такие вызовы асинхронных методов в Java. Это безопасно? Есть ли уже более простой способ?
источник
Ответы:
Я только что обнаружил, что есть более чистый способ
(По крайней мере, в Java 8) вы можете использовать лямбда-выражение, чтобы сократить его до:
Так же просто, как создать функцию на JS!
источник
Java 8 представила CompletableFuture, доступную в пакете java.util.concurrent.CompletableFuture, который можно использовать для выполнения асинхронного вызова:
источник
CompletableFuture
был упомянут в другом ответе, но тот использовал всюsupplyAsync(...)
цепочку. Это простая обертка, которая идеально подходит под вопрос.ForkJoinPool.commonPool().execute()
имеет немного меньше накладных расходовВы можете также рассмотреть класс
java.util.concurrent.FutureTask
.Если вы используете Java 5 или новее, FutureTask представляет собой готовую реализацию « отменяемого асинхронного вычисления».
В
java.util.concurrent
пакете доступны даже более широкие возможности асинхронного планирования выполнения (например,ScheduledExecutorService
), но ониFutureTask
могут иметь все необходимые вам функции.Я бы даже сказал, что больше не рекомендуется использовать первый шаблон кода, который вы привели в качестве примера с тех пор, как он
FutureTask
стал доступен. (Предполагая, что вы используете Java 5 или новее.)источник
Мне не нравится идея использовать для этого Reflection.
Это опасно не только из-за того, что его нельзя пропустить при рефакторинге, но и из-за того, что он может быть отвергнут
SecurityManager
.FutureTask
- хороший вариант, как и другие варианты из пакета java.util.concurrent.Мои любимые для простых задач:
немного короче, чем создание потока (задача - вызываемая или выполняемая)
источник
ExecutorService
экземпляром, поэтому вы можете позвонить,shutdown()
когда вам нужно.Вы можете использовать синтаксис Java8 для CompletableFuture, таким образом вы можете выполнять дополнительные асинхронные вычисления на основе результата вызова асинхронной функции.
например:
Более подробную информацию можно найти в этой статье.
источник
Вы можете использовать
@Async
аннотацию из jcabi-аспектов и AspectJ:Когда вы вызываете
save()
, запускается новый поток и выполняет свое тело. Ваш основной поток продолжается, не дожидаясь результатаsave()
.источник
Для этого вы можете использовать Future-AsyncResult.
Ссылка: https://spring.io/guides/gs/async-method/
источник
Java также предоставляет удобный способ вызова асинхронных методов. в java.util.concurrent у нас есть ExecutorService, который помогает делать то же самое. Инициализируйте свой объект следующим образом -
а затем вызовите функцию, например:
источник
Вероятно, это не настоящее решение, но теперь - в Java 8 - вы можете сделать этот код хотя бы немного лучше, используя лямбда-выражение.
И вы даже можете сделать это в одной строке, при этом все равно будет хорошо читаться.
источник
Вы можете использовать
AsyncFunc
от Cactoos :Он будет выполнен в фоновом режиме, а результат будет доступен в
get()
виде файлаFuture
.источник
На самом деле это не связано, но если бы я должен был асинхронно вызвать метод, например, match (), я бы использовал:
Затем для вызова асинхронного метода я бы использовал:
Я проверил это, и он работает. Просто подумал, что это может помочь другим, если они просто пришли за «асинхронным методом».
источник
Еще есть хорошая библиотека для Async-Await, созданная EA: https://github.com/electronicarts/ea-async
Из их Readme:
С EA Async
Без EA Async
источник