Call and pass parameter to method in another thread

cannot convert from 'method group to threadstart
c# run method in new thread with parameters
parameterizedthreadstart
pass parameter to thread java
c# pass parameter to thread
c# pass data between threads
c# thread with parameters and return value
parameterizedthreadstart multiple parameters c#

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?

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.

Creating threads and passing data at start time, This recipe will describe how to provide code that we run in another thread with the another method with the arguments needed and start it in another thread. Another way of passing parameters to a thread is by creating a closure. A closure is a scope that can inherit some of its parent's scope – we see it with lambdas and anonymous inner classes. Let's extend our previous example and create two threads.

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

ParameterizedThreadStart Delegate (System.Threading), The method reads the Person object details and prints them. We want to execute these methods in two separate worker threads. As you can  How not to pass arguments to threads in C++11. Don’t pass addresses of variables from local stack to thread’s callback function. Because it might be possible that local variable in Thread 1 goes out of scope but Thread 2 is still trying to access it through it’s address.

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

Passing parameters to a thread, In this tutorial, we'll run through different options available for passing parameters to a Java thread. 2. Thread Fundamentals. The Thread.Start method has an overloaded form that allows code to pass an object from main thread to a new thread. The object can be a simple data type or it can be a complex data type. The Thread class constructor takes either a ThreadStart delegate or a ParemeterizedThreadStart delegate.

Passing Data To A Thread In C# and .NET, This example C# program creates an array of 4 different threads. It starts a Thread Join. Next: ThreadStart is created with a constructor that receives a target function name. Then: The ThreadStart instance is passed as an argument to the Thread constructor. Info: The threads were called in a non-sequential order. When std::thread will internally create a new thread, it will use this passed member function as thread function. But to call a member function, we need a object. 2.) Pointer to the object of class Task As a second argument we passed a pointer to the object of class Task, with which above member function will be called.

Passing Parameters to Java Threads, Often when you start a thread, you want to give it some parameters - usually In some cases, you actually just wish to call a method in some class (possibly the These allow you to specify blocks of code as methods within other methods,  While Start() would start the thread and pass null as data to the method, Start() can be used to pass anything into the Work method of the thread. There is however one big problem with this approach: Everything passed into the Work method is cast into an object.

C# ThreadStart and ParameterizedThreadStart, Above, threadDemo is our thread function. Now pass a parameter to the thread − thread.Start(str);. The parameter set above is − String str  A parameter is a value that you can pass to a method in Java. Then the method can use the parameter as though it were a local variable initialized with the value of the variable passed to it by the calling method. The guessing-game application has a method named getRandomNumber that returns a random number …

Comments
  • What's the problem with updater.test(someVar)?
  • updater.test?
  • wouldn't test run on the main thread though? not the new thread I started for updater?
  • @Arya Your last sentence says How can I call test from the main thread ...
  • @Arya It's a bit unclear. Why not pass var the same way you pass new Date() to the constructor and call test from within the run() method? If the var value is only known to the main thread after threadUpdater has started, then you might want to use things like callbacks...
  • The futures example is very interesting. I'm going to see if I can use that in the main project
  • In the Main class I'm getting a red line under .supplyAsync(() with error "The method supplyAsync(Supplier<U>) in the type CompletableFuture is not applicable for the arguments (() -> {})"
  • Is getPage a void method in your version of Http?
  • @Arya If you prefer, you can keep it void (maybe you want to retrieve the response with a getter). If it's void, you'd have to use CompletableFuture<Void> future = CompletableFuture.runAsync(() -> http.get...
  • @ernest_k Will this example work if the user wants to supply a new URL for each thread? In your code, once you set the URL, each thread will call on that URL. What if the user wants to supply a custom URL to each thread using the same Http object?
  • I like this but unfortunately I can't use it since in my main project I have to use the Runnable method as the class is already extending another class
  • stackoverflow.com/questions/21871073/java-thread-vs-runnable It's the almost same docs.oracle.com/javase/7/docs/api/java/lang/Thread.html
  • In the main project I have public class OkHttp extends WebSocketListener implements Runnable I have to do extends WebSocketListener not sure how I can use your example