代码之家  ›  专栏  ›  技术社区  ›  Arya

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

  •  3
  • Arya  · 技术社区  · 7 年前

    我创建了这个小项目来展示我想要做的事情,但实际上它将用于使用大约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 我们开始初始化了 OkHttpClient client

    这可能吗?怎样才能做到呢?

    3 回复  |  直到 7 年前
        1
  •  1
  •   ernest_k Petronella    7 年前

    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();
            }
        }
    }
    

    而且,使用futures,您的主要方法看起来更简单:

    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 如果您需要更多地控制异步任务的运行方式。

        2
  •  0
  •   joshkmartinez    7 年前

    你可以打电话给 test 方法在 Updater 像这样的课程: updater.test(yourVarHere)
    this question
    您可能还想查看 Java concurrency tutorial

        3
  •  0
  •   Jonathan JOhx    7 年前

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