Thread オブジェクトのメソッドを直接呼び出すことはできません。Thread で同時実行性を取得する唯一の方法は、その start() メソッドを呼び出すことです。このメソッドは、別の実行スレッドで run() を呼び出します。main() から他のメソッドを直接呼び出すことは、通常の非 Thread オブジェクトでメソッドを呼び出すことと同じです。同時実行性はなく、特別なことは何も起こらず、メソッドはすぐに実行されます。
メインスレッドとワーカースレッドの間で通信しようとしているようです。各スレッドの run() メソッドは、そのスレッドでのコードの実行を担当します。その run() メソッドと通信できる場合は、そのスレッドで何が起こるかを制御できます。
これを行う 1 つの方法は、スレッドを構築するときに変数を渡すことです。run() メソッドが何をすべきかを判断するために調べることができる値を保存します。たとえば、以下の列挙型には 3 つの可能なアクションがあります。run() メソッドは列挙型を見て、WorkerThread() コンストラクターに渡された値に基づいて何をすべきかを決定します。
class WorkerThread {
public enum Action { DO_STUFF, MAKE_WIDGETS, FROB_BARS }
private Action action;
public WorkerThread(Action action) {
this.action = action;
}
public void run (){
switch (action) {
case DO_STUFF: doStuff(); break;
case MAKE_WIDGETS: makeWidgets(); break;
case FROB_BARS: frobBars(); break;
}
}
public void doStuff() { ... }
public void makeWidgets() { ... }
public void frobBars() { ... }
}
main() メソッドは次のようになります。実行するアクションを渡す WorkerThreads を作成してから、start() を呼び出します。
WorkerThread[] threads = new WorkerThread[10];
for (int i = 0; i < threads.length; ++i) {
threads[i] = new WorkerThread(WorkerThread.Action.DO_STUFF);
threads[i].start();
}
同じことを無数の異なる方法で行うことができます。WorkerThread クラスを 1 つ持つ代わりに、異なる run() メソッドを持ついくつかの異なるクラスを持ち、main() から適切なサブクラスをインスタンス化することができます。
class DoStuffWorkerThread extends Thread { ... }
class MakeWidgetsWorkerThread extends Thread { ... }
class FrobBarsWorkerThread extends Thread { ... }
必要に応じて、main() 内で匿名の Thread クラスを作成することもできます。次に、ロジックは main() が望むものであれば何でもかまいません。
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.length; ++i) {
threads[i] = new Thread() {
public void run() {
doStuff();
}
};
threads[i].start();
}