Reputation: 8965
I have created this small project to show what I want to do, but in reality it will be used in a large application which uses about 60 different threads.
I have two classes
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
}
}
and
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();
}
}
}
From the main thread, I want to be able to call the getPage
method but have it execute on the httpThread1
that we started and initialized OkHttpClient client
Is this possible? how can it be done?
Upvotes: 3
Views: 1111
Reputation: 5968
Based on your question, I think that you might do this:
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();
}
}
}
And in Main class:
public class Main {
public static void main(String[] args) {
Thread httpThread = new HttpThread(http, "httpThread1");
httpThread.start();
httpThread.getPage("http://google.com");
}
}
Upvotes: 0
Reputation: 45309
Runnable#run
is the method designed to do the actual work of a Runnable
object. So you would have to make it do what you're currently doing in getPage
.
You can use state to store url
, and save the response in a different field. See further comments about how you can refactor this to simplify it even further. But from the current code, the simplest changes could be:
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();
}
}
}
And in your main
method:
Http http = new Http("http://google.com");
Thread threadHttp = new Thread(http, "httpThread1");
threadHttp.start();
threadHttp.join();
Response resp = http.getResponse();
However, this can be substantially simplified with the use of futures. For example, it could look as simple as:
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();
}
}
}
And, using futures, your main method can look even simpler:
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();
}
You can even use a thread pool with supplyAsync
if you need more control over how asynchronous tasks run.
Upvotes: 1
Reputation: 664
You can call the test
method within the Updater
class like this: updater.test(yourVarHere)
To call a method within a separate thread see this question
You might also want to check out the Java concurrency tutorial
Upvotes: 0