您不能直接调用 Thread 对象上的方法。获得线程并发的唯一方法是调用它的 start() 方法,该方法又在单独的执行线程上调用 run()。直接从 main() 调用任何其他方法就像在常规非线程对象上调用方法一样;没有并发,没有什么特别的事情发生,方法立即执行。
听起来您正在尝试在主线程和工作线程之间进行通信。每个线程的 run() 方法负责在该线程上执行代码。如果您可以与该 run() 方法进行通信,那么您可以控制该线程上发生的事情。
一种方法是在构造线程时传入一个变量。保存 run() 方法可以检查以确定要执行的操作的值。例如,下面我们有一个枚举,其中包含三个可能的操作。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 类,您还可以拥有几个具有不同 run() 方法的不同类,然后从 main() 实例化适当的子类。
class DoStuffWorkerThread extends Thread { ... }
class MakeWidgetsWorkerThread extends Thread { ... }
class FrobBarsWorkerThread extends Thread { ... }
如果你愿意,你甚至可以在 main() 中创建匿名线程类。然后逻辑可以是任何 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();
}