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을 구현하고 Related 작업을 통해 올바른 메서드 객체를 얻고 호출하는 클래스를 사용하고 있다.
나는 나의 작은 도서관과 자바에서 이런 비동기식 전화를 하는 주제에 대해 의견을 갖고 싶다.그것은 안전한가요?이미 간단한 방법이 있는가?
나는 방금 너의 일을 더 깨끗하게 할 수 있는 방법이 있다는 것을 알았다.
new Thread(new Runnable() {
public void run() {
//Do whatever
}
}).start();
(적어도 자바 8에서는) 람다 식을 사용하여 다음과 같이 단축할 수 있다.
new Thread(() -> {
//Do whatever
}).start();
JS에서 기능을 만드는 것만큼 간단해!
Java 8에서 Completetable을 도입함향후 Java.util.concurrent 패키지에서 사용 가능.Completable미래, 비동기 통화에 사용할 수 있음:
CompletableFuture.runAsync(() -> {
// method call or code to be asynch.
});
당신은 또한 수업을 고려하기를 원할지도 모른다.java.util.concurrent.FutureTask
.
Java 5 이상을 사용하는 경우, FutureTask는 "A 취소 가능한 비동기 연산"의 턴키 구현이다.
.java.util.concurrent
패키地(예地:ScheduledExecutorService
)) 그러나FutureTask
필요한 모든 기능을 가질 수 있다.
나는 심지어 그 이후로 당신이 첫번째로 준 코드 패턴을 예시로 사용하는 것은 더 이상 바람직하지 않다고까지 말하고 싶다.FutureTask
이용할 수 있게 되었다.(Java 5 이상일 것으로 가정)
반사를 이용하는 게 맘에 안 들어
어떤 리팩터링에서 놓치면 위험할 뿐만 아니라, 에 의해 거부될 수도 있다.SecurityManager
.
FutureTask
dutil.dutil.detail.data.details의 이다.
간단한 작업에 가장 좋아하는 항목:
Executors.newSingleThreadExecutor().submit(task);
스레드를 만드는 것보다 약간 짧음(태스크는 호출 가능 또는 실행 가능)
Completetable에 Java8 구문을 사용할 수 있음미래에는 이러한 방식으로 비동기 함수를 호출한 결과에 따라 추가 비동기 계산을 수행할 수 있다.
예를 들면 다음과 같다.
CompletableFuture.supplyAsync(this::findSomeData)
.thenApply(this:: intReturningMethod)
.thenAccept(this::notify);
자세한 내용은 이 기사를 참조하십시오.
jcabi-ascendors 및 SensionJ의 주석을 사용할 수 있다.
public class Foo {
@Async
public void save() {
// to be executed in the background
}
}
전화할 때save()
, 새로운 실이 시작되고 그 몸을 실행한다.결과를 기다리지 않고 메인 스레드가 계속됨save()
.
자바는 또한 비동기식 방법을 부르는 좋은 방법을 제공한다.java.util.concurrent에서는 동일한 작업을 수행하는 데 도움이 되는 ExecutorService를 가지고 있다.이렇게 개체 초기화 -
private ExecutorService asyncExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
그런 다음 함수를 다음과 같이 부른다.
asyncExecutor.execute(() -> {
TimeUnit.SECONDS.sleep(3L);}
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/
선인장에서 사용 가능:
boolean matches = new AsyncFunc(
x -> x.matches("something")
).apply("The text").get();
그것은 백그라운드에서 실행될 것이고 그 결과는 에서 이용할 수 있을 것이다.get()
로서Future
.
이것은 실제로 관련이 없지만 만약 내가 비동기적으로 매칭() 메서드를 호출한다면, 나는 다음을 사용할 것이다.
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();
}
나는 이것을 시험해 보았는데 효과가 있다.단지 그들이 "비동기적 방법"을 위해 온다면 다른 사람들에게 도움이 될 수 있다고 생각했다.
이것은 아마도 진정한 해결책은 아니지만, 자바 8에서는 이 코드를 람다 표현으로 조금 더 좋게 만들 수 있다.
final String x = "somethingelse";
new Thread(() -> {
x.matches("something");
}
).start();
그리고 한 줄에 이렇게 할 수도 있지
new Thread(() -> x.matches("something")).start();
또한 EA에서 만든 Async-Await를 위한 멋진 라이브러리도 있다: https://github.com/electronicarts/ea-async
보낸 사람:
EA 비동기 포함
import static com.ea.async.Async.await;
import static java.util.concurrent.CompletableFuture.completedFuture;
public class Store
{
public CompletableFuture<Boolean> buyItem(String itemTypeId, int cost)
{
if(!await(bank.decrement(cost))) {
return completedFuture(false);
}
await(inventory.giveItem(itemTypeId));
return completedFuture(true);
}
}
EA 비동기 미포함
import static java.util.concurrent.CompletableFuture.completedFuture;
public class Store
{
public CompletableFuture<Boolean> buyItem(String itemTypeId, int cost)
{
return bank.decrement(cost)
.thenCompose(result -> {
if(!result) {
return completedFuture(false);
}
return inventory.giveItem(itemTypeId).thenApply(res -> true);
});
}
}
참조URL: https://stackoverflow.com/questions/1842734/how-to-asynchronously-call-a-method-in-java
'programing' 카테고리의 다른 글
Java: 날짜 생성자가 더 이상 사용되지 않는 이유와 내가 대신 사용하는 것은? (0) | 2022.04.13 |
---|---|
JUnit를 사용하여 비동기 프로세스를 테스트하는 방법 (0) | 2022.04.13 |
getter(Vuex)에서 상태를 호출할 때 정의되지 않음 (0) | 2022.04.13 |
Vue에서 계산된 속성/게터 디버링 (0) | 2022.04.13 |
Vue, Vuex: 이름을 앞지르고 조롱하는 구성 요소를 어떻게 유닛화하는지? (0) | 2022.04.13 |