최근 에 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을 구현하는 클래스를 사용하고 있으며 올바른 메서드 개체를 가져 와서 호출하기 위해 몇 가지 Reflection 작업을 수행합니다.
내 작은 라이브러리와 Java에서 이와 같은 비동기 메서드 호출을 만드는 주제에 대한 의견이 필요합니다. 안전 해요? 이미 더 간단한 방법이 있습니까?
답변
나는 당신을 할 수있는 더 깨끗한 방법이 있음을 방금 발견했습니다.
new Thread(new Runnable() {
public void run() {
//Do whatever
}
}).start();
(적어도 Java 8에서는) 람다 식을 사용하여 다음과 같이 줄일 수 있습니다.
new Thread(() -> {
//Do whatever
}).start();
JS에서 함수를 만드는 것처럼 간단합니다!
답변
Java 8은 java.util.concurrent.CompletableFuture 패키지에서 사용할 수있는 CompletableFuture를 도입했으며 비동기 호출을 만드는 데 사용할 수 있습니다.
CompletableFuture.runAsync(() -> {
// method call or code to be asynch.
});
답변
수업을 고려할 수도 있습니다 java.util.concurrent.FutureTask
.
Java 5 이상을 사용하는 경우 FutureTask 는 “취소 가능한 비동기 계산”의 턴키 구현입니다.
java.util.concurrent
패키지 에서 사용할 수있는 더 풍부한 비동기 실행 스케줄링 동작 (예 :)이 ScheduledExecutorService
있지만 FutureTask
필요한 모든 기능이있을 수 있습니다.
심지어 사용 FutureTask
가능해진 이후로 예제로 제공 한 첫 번째 코드 패턴을 더 이상 사용하지 않는 것이 좋습니다 . (Java 5 이상을 사용한다고 가정합니다.)
답변
나는 그것을 위해 Reflection을 사용하는 아이디어가 마음에 들지 않습니다.
일부 리팩토링에서 누락되어 위험 할뿐만 아니라 SecurityManager
.
FutureTask
java.util.concurrent 패키지의 다른 옵션과 마찬가지로 좋은 옵션입니다.
내가 가장 좋아하는 간단한 작업 :
Executors.newSingleThreadExecutor().submit(task);
조금 (작업이 호출 가능 또는의 Runnable입니다) 스레드를 만드는 것보다 짧은 비트
답변
CompletableFuture에 Java8 구문을 사용할 수 있습니다. 이렇게하면 비동기 함수 호출의 결과를 기반으로 추가 비동기 계산을 수행 할 수 있습니다.
예를 들면 :
CompletableFuture.supplyAsync(this::findSomeData)
.thenApply(this:: intReturningMethod)
.thenAccept(this::notify);
자세한 내용은이 기사 에서 찾을 수 있습니다.
답변
jcabi-aspects 및 AspectJ의 @Async
주석을 사용할 수 있습니다 .
public class Foo {
@Async
public void save() {
// to be executed in the background
}
}
를 호출 save()
하면 새 스레드가 시작되고 본문을 실행합니다. 의 결과를 기다리지 않고 주 스레드가 계속됩니다 save()
.
답변
이를 위해 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);
}