我已经创建了这个小项目来展示我想做的事,但实际上,它将被用在使用大约60个不同线程的大型应用程序中。
我有两个课
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
的{{1}}上执行
这可能吗?该怎么办?
答案 0 :(得分:1)
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
一起使用。
答案 1 :(得分:0)
您可以在test
类中调用Updater
方法,如下所示:updater.test(yourVarHere)
要在单独的线程中调用方法,请参见this question
您可能还想查看Java concurrency tutorial
答案 2 :(得分:0)
根据您的问题,我认为您可以这样做:
class HttpThread extends Thread {
volatile OkHttpClient client;
HttpThread(Runnable target, String name) {
super(target, name);
}
@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();
}
}
}
在主类中:
public class Main {
public static void main(String[] args) {
Thread httpThread = new HttpThread(http, "httpThread1");
httpThread.start();
httpThread.getPage("http://google.com");
}
}