所以我试图让一些线程在没有干预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
类内)
所以他们不应该按顺序完成。
答案 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
}