调用并将参数传递给另一个线程中的方法

时间:2019-01-06 07:11:06

标签: java multithreading

我已经创建了这个小项目来展示我想做的事,但实际上,它将被用在使用大约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}}上执行

这可能吗?该怎么办?

3 个答案:

答案 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"); 
    }
}