线程不会开火而忘记

时间:2015-04-02 16:35:28

标签: java multithreading

所以我试图让一些线程在没有干预java的情况下自行启动和运行。

线程是通过扩展线程类来实现的:

public class MyThread extends Thread{
public void run(){
    executeEvents();
}

executeEvents里面有很多业务逻辑。

然而,在调用之前,线程是这样的:

public MyThread(int threadNumber, ArrayList<Event> events, Mailbox mailbox){
    this.events = events;
    this.mailbox = mailbox;
    this.threadNumber = threadNumber;
}

并且主要是创建了这些线程的数组,然后应该启动

    public static void spawnThreads(int numOfThreads){
    Mailbox mailbox = new Mailbox(numOfThreads);
    MyThread[] threads = new MyThread[numOfThreads];
    ArrayList<Event> events = spawnEvents(numOfThreads*10,numOfThreads);
    ArrayList<Event>[] eventsForThread = new ArrayList[numOfThreads];
    Random rng = new Random();
    for(int i = 0; i < eventsForThread.length; i++){
        eventsForThread[i] = new ArrayList<Event>();
    }
    for(int i = 0; i < events.size(); i++){
        eventsForThread[rng.nextInt(numOfThreads)].add(events.get(i));
    }
    for(int i = 0; i < threads.length; i++){
        threads[i] = new MyThread();
        threads[i].start();
        threads[i].addToMyThread(i,eventsForThread[i],mailbox);
        threads[i].executeEvents();
    }
   // executeEvents(threads,mailbox);
}

然而由于某些原因,当这个运行时,线程不是以并行方式启动而是按顺序启动,我无法弄清楚原因。

我可以看到它没有并行运行,因为arraylist中的每个事件都有一个随机等待

public void executeEvent(){
    try {
        Random rng2 = new Random(); 
        Thread.sleep(rng2.nextInt(400));
    } catch (InterruptedException ex) {
        Logger.getLogger(Event.class.getName()).log(Level.SEVERE, null, ex);
    }
    }

(这是在Event类内)

所以他们不应该按顺序完成。

1 个答案:

答案 0 :(得分:4)

您应该使用Thread#start()方法而不是Thread#run()。后者不会产生并行运行的线程:

for(int i = 0; i < threads.length; i++){
    threads[i] = new Thread(new MyThread(i,eventsForThread[i],mailbox));
    threads[i].start();
}

来自start方法的Javadoc:

  

使该线程开始执行; Java虚拟机调用此线程的run方法。

     

结果是两个线程并发运行:当前线程(从调用start方法返回)和另一个线程(执行其run方法)。

<强>更新

更新后的问题后,问题似乎与以下内容有关:

for(int i = 0; i < threads.length; i++){
    threads[i] = new MyThread();
    threads[i].start();
    threads[i].addToMyThread(i,eventsForThread[i],mailbox);
    threads[i].executeEvents(); // this is causing the serial execution
}

方法start()将生成一个新线程,但在此之后你会调用threads[i].executeEvents()阻塞它直到它返回。这不是应该如何实施的。 start方法已调用run MyThread方法,后者又调用executeEvents。您只需致电start。将事件“添加”到线程的部分应该在此调用之前,例如:

for(int i = 0; i < threads.length; i++){
    threads[i] = new MyThread();
    threads[i].addToMyThread(i,eventsForThread[i],mailbox);
    threads[i].start();  // this will call executeEvents in a separate thread
}