web-dev-qa-db-ja.com

Javaスレッドにパラメータを渡す方法

スレッドにパラメータを渡す方法を誰かに教えてもらえますか。

また、無名クラスではどのように機能しますか?

269
Steve

コンストラクタのパラメータをRunnableオブジェクトに渡す必要があります。

public class MyRunnable implements Runnable {

   public MyRunnable(Object parameter) {
       // store parameter for later user
   }

   public void run() {
   }
}

そしてそれを次のように呼び出します。

Runnable r = new MyRunnable(param_value);
new Thread(r).start();
348
Alnitak

匿名クラスの場合:

ここでの質問の編集に応えて、Anonymousクラスでどのように機能するかを説明します。

   final X parameter = ...; // the final is important
   Thread t = new Thread(new Runnable() {
       p = parameter;
       public void run() { 
         ...
       };
   t.start();

名前付きクラス

Threadを拡張する(またはRunnableを実装する)クラスと、渡したいパラメータを持つコンストラクタがあります。次に、新しいスレッドを作成するときに、引数を渡してからスレッドを開始する必要があります。

Thread t = new MyThread(args...);
t.start();

RunnableはThread BTWよりもはるかに優れたソリューションです。だから私は好きです:

   public class MyRunnable implements Runnable {
      private X parameter;
      public MyRunnable(X parameter) {
         this.parameter = parameter;
      }

      public void run() {
      }
   }
   Thread t = new Thread(new MyRunnable(parameter));
   t.start();

この答えは基本的にこの同じような質問と同じです。 Threadオブジェクトにパラメータを渡す方法

103
Nick Fortescue

runnableまたはThreadクラスのコンストラクタを介して

class MyThread extends Thread {

    private String to;

    public MyThread(String to) {
        this.to = to;
    }

    @Override
    public void run() {
        System.out.println("hello " + to);
    }
}

public static void main(String[] args) {
    new MyThread("world!").start();
}
40
dfa

この答えは非常に遅れて来ます、しかし多分誰かがそれが役に立つと思うでしょう。名前付きクラスさえ宣言せずにRunnableにパラメータを渡す方法についてです(インライナーには便利です):

String someValue = "Just a demo, really...";
new Thread(new Runnable() {
    private String myParam;
    public Runnable init(String myParam) {
        this.myParam = myParam;
        return this;
    }
    @Override
    public void run() {
        System.out.println("This is called from another thread.");
        System.out.println(this.myParam);
    }
}.init(someValue)).start();

もちろん、あなたはstartの実行をもっと便利な、あるいは適切な時期に延期することができます。そしてそれはinitメソッドのシグネチャが何であるか(それにより多くのそして/または異なる引数を取るかもしれません)そしてもちろんその名前さえあなた次第ですが、基本的にあなたはアイデアを得ます。

実際、初期化子ブロックを使って、無名クラスにパラメータを渡す別の方法もあります。このことを考慮:

String someValue = "Another demo, no serious thing...";
int anotherValue = 42;

new Thread(new Runnable() {
    private String myParam;
    private int myOtherParam;
    {
        this.myParam = someValue;
        this.myOtherParam = anotherValue;
    }
    @Override
    public void run() {
        System.out.println("This comes from another thread.");
        System.out.println(this.myParam + ", " + this.myOtherParam);
    }
}).start();

したがって、すべてinitializerブロックの内部で発生します。

18
Cromax

スレッドを作成するときは、Runnableのインスタンスが必要です。パラメータを渡す最も簡単な方法は、コンストラクタへの引数として渡すことです。

public class MyRunnable implements Runnable {

    private volatile String myParam;

    public MyRunnable(String myParam){
        this.myParam = myParam;
        ...
    }

    public void run(){
        // do something with myParam here
        ...
    }

}

MyRunnable myRunnable = new myRunnable("Hello World");
new Thread(myRunnable).start();

スレッドの実行中にパラメータを変更したい場合は、実行可能クラスにsetterメソッドを追加するだけです。

public void setMyParam(String value){
    this.myParam = value;
}

これを取得したら、次のように呼び出してパラメータの値を変更できます。

myRunnable.setMyParam("Goodbye World");

もちろん、パラメータが変更されたときにアクションを起動したい場合は、ロックを使用する必要があります。これは、状況をかなり複雑にします。

17
jwoolard

スレッドを作成するには、通常独自のRunnableの実装を作成します。このクラスのコンストラクタでスレッドにパラメータを渡します。

class MyThread implements Runnable{
   private int a;
   private String b;
   private double c;

   public MyThread(int a, String b, double c){
      this.a = a;
      this.b = b;
      this.c = c;
   }

   public void run(){
      doSomething(a, b, c);
   }
}
9
Mnementh

Threadclassまたは Runnableclassを拡張してパラメータを指定することができます。あなたが望むように。 ドキュメント に簡単な例があります。それらをここに移植します。

 class PrimeThread extends Thread {
     long minPrime;
     PrimeThread(long minPrime) {
         this.minPrime = minPrime;
     }

     public void run() {
         // compute primes larger than minPrime
          . . .
     }
 }

 PrimeThread p = new PrimeThread(143);
 p.start();

 class PrimeRun implements Runnable {
     long minPrime;
     PrimeRun(long minPrime) {
         this.minPrime = minPrime;
     }

     public void run() {
         // compute primes larger than minPrime
          . . .
     }
 }


 PrimeRun p = new PrimeRun(143);
 new Thread(p).start();
8
bruno conde

Runnableを実装するクラスを作成し、適切に定義されたコンストラクタに必要なものを渡すか、適切なパラメータを使用してsuper()を呼び出す適切に定義されたコンストラクタを使用してThreadを拡張するクラスを作成します。

7
PaulJWilliams

Java 8以降では、ラムダを使用して 事実上最終的な パラメータを取得できます。例えば:

final String param1 = "First param";
final int param2 = 2;
new Thread(() -> {
    // Do whatever you want here: param1 and param2 are in-scope!
    System.out.println(param1);
    System.out.println(param2);
}).start();
5
Jeff G

あなたはRunnableからクラスを派生させることができ、そして構築中に(例えば)パラメータを渡します。

次にThread.start(Runnable r)を使って起動します。

whilstの場合は、呼び出し元のスレッドで派生オブジェクトへの参照を保持し、適切な設定メソッドを呼び出します(必要に応じて同期します)。

3
Brian Agnew

Start()およびrun()メソッドを介したパラメータ渡し

// Tester
public static void main(String... args) throws Exception {
    ThreadType2 t = new ThreadType2(new RunnableType2(){
        public void run(Object object) {
            System.out.println("Parameter="+object);
        }});
    t.start("the parameter");
}

// New class 1 of 2
public class ThreadType2 {
    final private Thread thread;
    private Object objectIn = null;
    ThreadType2(final RunnableType2 runnableType2) {
        thread = new Thread(new Runnable() {
            public void run() {
                runnableType2.run(objectIn);
            }});
    }
    public void start(final Object object) {
        this.objectIn = object;
        thread.start();
    }
    // If you want to do things like setDaemon(true); 
    public Thread getThread() {
        return thread;
    }
}

// New class 2 of 2
public interface RunnableType2 {
    public void run(Object object);
}
3
Java42

パラメータをランナブルに渡す簡単な方法があります。コード:

public void Function(final type variable) {
    Runnable runnable = new Runnable() {
        public void run() {
            //Code adding here...
        }
    };
    new Thread(runnable).start();
}
2
Chromium

Java 8では、 Concurrency APIlambdaを使って、スレッドを直接操作するためのExecutorService式を使用できます。

newCachedThreadPool()必要に応じて新しいスレッドを作成するスレッドプールを作成しますが、以前に構築されたスレッドが利用可能になるとそれを再利用します。これらのプールは通常、短期間の多くの非同期タスクを実行するプログラムのパフォーマンスを向上させます。

    private static final ExecutorService executor = Executors.newCachedThreadPool();

    executor.submit(() -> {
        myFunction(myParam1, myParam2);
    });

executorsjavadocs もご覧ください。

2
Stuart Cardall

私は数年遅れていることを知っていますが、私はこの問題に遭遇し、非正統的なアプローチを取りました。私は新しいクラスを作らずにそれをやりたかったので、これが私が思いついたものです:

int x = 0;
new Thread((new Runnable() {
     int x;
     public void run() {
        // stuff with x and whatever else you want
     }
     public Runnable pass(int x) {
           this.x = x;
           return this;
     }
}).pass(x)).start();
1
meyi

Android専用

コールバックの目的で、私は通常、入力パラメータを使って私自身の一般的なRunnableを実装します。

public interface Runnable<TResult> {
    void run(TResult result);
}

使い方は簡単です。

myManager.doCallbackOperation(new Runnable<MyResult>() {
    @Override
    public void run(MyResult result) {
        // do something with the result
    }
});

マネージャーで:

public void doCallbackOperation(Runnable<MyResult> runnable) {
    new AsyncTask<Void, Void, MyResult>() {
        @Override
        protected MyResult doInBackground(Void... params) {
            // do background operation
            return new MyResult(); // return resulting object
        }

        @Override
        protected void onPostExecute(MyResult result) {
            // execute runnable passing the result when operation has finished
            runnable.run(result);
        }
    }.execute();
}
1
Andrei

いいえ、run()メソッドにパラメータを渡すことはできません。シグネチャはそれを示しています(パラメータはありません)。おそらくこれを行う最も簡単な方法は、コンストラクタ内のパラメータを受け取り、それを最終変数に格納する、専用のオブジェクトを使用することです。

public class WorkingTask implements Runnable
{
    private final Object toWorkWith;

    public WorkingTask(Object workOnMe)
    {
        toWorkWith = workOnMe;
    }

    public void run()
    {
        //do work
    }
}

//...
Thread t = new Thread(new WorkingTask(theData));
t.start();

それができたら - あなたは 'WorkingTask'に渡すオブジェクトのデータの完全性に注意しなければなりません。データは2つの異なるスレッドに存在するようになるので、スレッドセーフであることを確認する必要があります。

1
Mihir Patel

もう一つの選択肢。この方法では、非同期関数呼び出しのようにRunnable項目を使用できます。タスクが結果を返す必要がない場合は、 「結果」を返す方法について心配する必要がないアクションを実行するだけです。

このパターンはあなたがアイテムを再利用することを可能にします、そこであなたはある種の内部状態を必要とします。コンストラクタでパラメータを渡さない場合は、プログラムによるパラメータへのアクセスを仲介するために注意が必要です。あなたのユースケースが異なる呼び出し元などを含む場合、あなたはより多くのチェックが必要になるかもしれません。

public class MyRunnable implements Runnable 
{
  private final Boolean PARAMETER_LOCK  = false;
  private X parameter;

  public MyRunnable(X parameter) {
     this.parameter = parameter;
  }

  public void setParameter( final X newParameter ){

      boolean done = false;
      synchronize( PARAMETER_LOCK )
      {
          if( null == parameter )
          {
              parameter = newParameter;
              done = true;
          }
      }
      if( ! done )
      {
          throw new RuntimeException("MyRunnable - Parameter not cleared." );
      }
  }


  public void clearParameter(){

      synchronize( PARAMETER_LOCK )
      {
          parameter = null;
      }
  }


  public void run() {

      X localParameter;

      synchronize( PARAMETER_LOCK )
      {
          localParameter = parameter;
      }

      if( null != localParameter )
      {
         clearParameter();   //-- could clear now, or later, or not at all ...
         doSomeStuff( localParameter );
      }

  }

}

スレッドt =新しいスレッド(新しいMyRunable(パラメータ))。 t.start();

処理結果が必要な場合は、サブタスクが終了したときにMyRunnableの完了を調整する必要もあります。あなたはコールバックを渡すか、単にスレッド 't'などを待つことができます.

1
will

クラス内にextends Threadまたはimplements Runnableというローカル変数を作成します。

public class Extractor extends Thread {
    public String webpage = "";
    public Extractor(String w){
        webpage = w;
    }
    public void setWebpage(String l){
        webpage = l;
    }

    @Override
    public void run() {// l is link
        System.out.println(webpage);
    }
    public String toString(){
        return "Page: "+webpage;
    }}

これにより、実行時に変数を渡すことができます。

Extractor e = new Extractor("www.google.com");
e.start();

出力:

"www.google.com"
0
calvin k