アルヤ:
私は私が何をしたいのか表示するには、この小さなプロジェクトを作成しているが、実際には60の異なるスレッドについて使用する大規模なアプリケーションに使用されます。
私は2つのクラスを持っています
public class Main {
public static void main(String[] args) {
Http http = new Http();
Thread threadHttp = new Thread(http, "httpThread1");
threadHttp.start();
http.getPage("http://google.com"); // <-- This gets called on
// the main thread,
//I want it to get called from the
// "httpThread1" thread
}
}
そして
public class Http implements Runnable {
volatile OkHttpClient client;
@Override
public void run() {
client = new OkHttpClient.Builder().readTimeout(10, TimeUnit.SECONDS).retryOnConnectionFailure(true).build();
}
public void getPage(String url) {
Request request = new Request.Builder().url(url).build();
try {
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
} catch (Exception e) {
e.printStackTrace();
}
}
}
メインスレッドからは、私が呼び出すことができるようにしたいgetPage
メソッドを、それは上で実行しているhttpThread1
私たちが開始され、初期化されていることOkHttpClient client
これは可能ですか?それはどのように行うことができますか?
ernest_k:
Runnable#run
実際の作業を行うために設計された方法であるRunnable
オブジェクトを。あなたが作るしなければならないので、それはあなたが現在でやっているものを行いますgetPage
。
あなたは店に状態を使用することができurl
、異なる分野での応答を保存します。あなたはさらにそれを簡単にするために、これをリファクタリングする方法についてさらにコメントを参照してください。しかし、現在のコードから、最も簡単な変更は次のようになります。
class Http implements Runnable {
//initialize Http. This can be done better perhaps
volatile OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(10, TimeUnit.SECONDS)
.retryOnConnectionFailure(true).build();
private Response response;
private String url;
public Http(String url) {
this.url = url;
}
@Override
public void run() {
this.getPage(this.url);
}
public void getPage(String url) {
Request request = new Request.Builder().url(url).build();
try {
this.response = client.newCall(request).execute();
System.out.println(response.body().string());
} catch (Exception e) {
e.printStackTrace();
}
}
}
そして、あなたの中main
の方法:
Http http = new Http("http://google.com");
Thread threadHttp = new Thread(http, "httpThread1");
threadHttp.start();
threadHttp.join();
Response resp = http.getResponse();
しかし、これは、実質的に先物を使用して簡素化することができます。例えば、それは簡単なようようになります:
class Http {
volatile OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(10, TimeUnit.SECONDS)
.retryOnConnectionFailure(true).build();
public Response getPage(String url) {
Request request = new Request.Builder().url(url).build();
try {
this.response = client.newCall(request).execute();
System.out.println(response.body().string());
} catch (Exception e) {
e.printStackTrace();
}
}
}
そして、先物を使用して、あなたの主な方法は、さらに簡単見ることができます:
public static void main(String[] args) throws Exception {
Http http = new Http();
CompletableFuture<Response> future =
CompletableFuture.supplyAsync(() -> http.getPage("http://google.com"));
//the preceding statement will call `getPage` on a different thread.
//So you can do other things before blocking with next statement
Response resp = future.join();
}
あなたもしてスレッドプールを使用することができsupplyAsync
ますが、非同期タスクの実行方法をより詳細に制御する必要がある場合。