Java线程与run方法

Java线程与run方法,java,multithreading,Java,Multithreading,我正在编写一个使用一些线程的Java应用程序。主要方法如下所示: WorkerThread[] thread = new WorkerThread(); for (int i = 0 ; i<10 ; i++) { thread = new WorkerThread(); thread.doStuff(); } class WorkerThread { public void run() { ... } public void d

我正在编写一个使用一些线程的Java应用程序。主要方法如下所示:

WorkerThread[] thread = new WorkerThread();
for (int i = 0 ; i<10 ; i++) {
    thread = new WorkerThread();
    thread.doStuff();
}
class WorkerThread {
    public void run() {
        ...
    }

    public void doStuff() {
        ...
    }
}
class WorkerA implements Runnable {            

    public void run (){
        ...
        // put here your code from doStuff in one Version
        ...
    }

}

class WorkerB implements Runnable {

    public void run (){
        ...
        // put here your code from doStuff in an other Version
        ...
    }

}
问题是,很明显,我从run方法调用doStuff,它与其他线程一样并发执行,但如果我直接从main调用doStuff,它就不会并发执行


好的,现在的问题是:是否有一种方法可以并发执行doStuff方法,该方法不是从run方法调用它,而是从main调用它?

当您使用
thread.doStuff()时
您没有使用线程,至于使用线程,您必须调用
thread.start()
方法,该方法将在内部调用
run()
方法

 Thread[] threads = new Thread()[10];
    for (int i = 0 ; i<10 ; i++) {
        if ( i<5) {
          threads[i] = new Thread(new WorkerA());
        } else {
          threads[i] = new Thread(new WorkerB());
        }
        threads[i].start();
    }

现在,您可以在引用数组的任何位置调用它,而不是在循环中调用
线程[i].start()

您可以使用
Runnable

// Dictate what work needs to be done
Runnable work = new Work(); // or new OtherWork();

Thread thread = new Thread(work);
thread.start();

class Work implements Runnable {
    public void run(){
        System.out.println("do stuff");
    }
}

class OtherWork implements Runnable {
    public void run() {
        System.out.println(" do other stuff");
    }
}
编辑
建议使用线程池,而不是为每个任务创建(和丢弃)线程。这是因为在创建/丢弃线程时会有一些开销,而且它还可以更容易地管理任务应该在什么并发状态下执行等等

无论如何,您可以使用
thread
类自己创建线程池,但这需要大量的工作,而且很难做到正确。相反,最好使用JDK中现成的解决方案。您可以按如下方式使用它:

ExecutorService threadPool = Executors.newFixedThreadPool(4);
threadPool.execute(new Work());
threadPool.execute(new OtherWork());

// After submitting all your task (or when your application wants to terminate)
// You should call shutdown() on the thread pool so that the JVM can exit
threadPool.shutdown();

不能直接调用线程对象上的方法。获取线程并发性的唯一方法是调用其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()


如果愿意,您甚至可以在main()内创建匿名线程类。然后,逻辑可以是main()想要的任何东西

Thread[]threads=新线程[10];
对于(int i=0;i
有,在
main
中创建匿名
Runnable
s,但是为什么呢?我猜他的run方法有他不想在所有情况下都执行的逻辑。我强烈建议您检查并发包中的类,而不是编写原始线程,并阅读“Java中的并发性”以避免对此提出太多的观点,但是你需要学习更多关于用Java编写多线程代码的知识,以便在尝试任何东西之前理解基本概念。@BenBrunk如果你给我一个我能理解的提示,但是如果你不这样做,你怎么能帮助我呢?我需要的是在运行时调用正确的方法:我没有一些代码总是要执行。我必须能够从mainok中选择正确的方法,但这样我就不能选择WorkerThread的方法在运行时调用!也许我应该扩展一个抽象类,它在ITI上实现runnable和call run,如果您认为每个类中需要几乎相同的例程和字段,但执行的方式不同,那么扩展一个抽象类应该完成这项工作。此外,您还应该创建自己的类来实现Runnable接口。因此,您认为,我应该创建一些执行特定作业的线程,并只运行主题。@litiales:推荐的方法是使用线程池。不过,为每个特定作业创建一个线程也可以。只是效率不高。我已经创建了一个FixedThreadPool!但它又能帮我什么忙呢?太好了,我还没想到这个实现呢。很好:-)我不认为这是一种在交换情况下处理不同作业的好方法?如果代码增长,那么维护它就变得很困难。使用单独的Runnable或classe,以后更容易扩展功能。
WorkerThread[] threads = new WorkerThread[10];
for (int i = 0; i < threads.length; ++i) {
    threads[i] = new WorkerThread(WorkerThread.Action.DO_STUFF);
    threads[i].start();
}
class DoStuffWorkerThread     extends Thread { ... }
class MakeWidgetsWorkerThread extends Thread { ... }
class FrobBarsWorkerThread    extends Thread { ... }
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.length; ++i) {
    threads[i] = new Thread() {
        public void run() {
            doStuff();
        }
    };

    threads[i].start();
}