Java产卵幽灵线程
我正在研究一种新的NLP分类器算法,并希望使其成为多线程。我的实现执行它应该正确执行的操作,但在运行threads = 4时出现一些奇怪的异常。 这是我的方法:Java产卵幽灵线程
protected void generateCoordinatesMultiThread(Category generate, int threads){
WordMap wordMap = new WordMap();
wordOccurences = new int[semanticspace.getVectorAmount()][generate.getSize()];
tfidf = new double[semanticspace.getVectorAmount()][generate.getSize()];
ntfidf = new double[semanticspace.getVectorAmount()][generate.getSize()];
Thread[] threadGroup = new Thread[threads];
try{
System.out.println(generate.getSize()+" objects in "+threads+" threads");
for(int i=0;i<threads;i++){
int start=(generate.getSize()/threads)*i;
int end=((generate.getSize()/threads)*(i+1))-1;
if(i==threads-1){
end=generate.getSize();
}
System.out.println("Start: "+start+" end: "+end);
threadGroup[i] = new Thread(new WordMapper(this,start,end,generate,"WordMapper-"+i,wordMap));
threadGroup[i].start();
}
for(int i=0;i<threads;i++){
threadGroup[i].join();
}
System.out.println("First multi-thread step finished");
wordMap.mapSemanticSpace(semanticspace);
wordMap.print();
}catch(Exception e){
System.out.println(e.getMessage());
}
System.out.println("Starting frequency workers");
threadGroup = new Thread[threads];
try{
System.out.println(generate.getSize()+" objects in "+threads+" threads");
for(int i=0;i<threads;i++){
int start=(generate.getSize()/threads)*i;
int end=((generate.getSize()/threads)*(i+1))-1;
if(i==threads-1){
end=generate.getSize();
}
System.out.println("Start: "+start+" end: "+end);
threadGroup[i] = new Thread(new FrequencyWorker(this,start,end,generate,"FrequencyWorker-"+i,wordMap));
threadGroup[i].start();
}
for(int i=0;i<threads;i++){
threadGroup[i].join();
}
System.out.println("Second multi-thread step finished");
}catch(Exception e){
System.out.println(e.getMessage());
}
System.out.println("Starting coordinate generators");
threadGroup = new Thread[threads];
try{
System.out.println(generate.getSize()+" objects in "+threads+" threads");
for(int i=0;i<threads;i++){
int start=(generate.getSize()/threads)*i;
int end=((generate.getSize()/threads)*(i+1))-1;
if(i==threads-1){
end=generate.getSize();
}
System.out.println("Start: "+start+" end: "+end);
threadGroup[i] = new Thread(new CoordinateGenerator(this,start,end,generate,"FrequencyWorker-"+i,wordMap));
threadGroup[i].start();
}
for(int i=0;i<threads;i++){
threadGroup[i].join();
}
System.out.println("Third multi-thread step finished");
}catch(Exception e){
System.out.println(e.getMessage());
}
}
这让我异常:在线程
异常 “主题-5” 显示java.lang.NullPointerException
在semanticobjects.WordMapper.run(WordMapper的.java:21)
在java.lang.Thread.run(Thread.java:695)
与9和13相同。这两个数字在运行线程数= 4时不应该首先生成。结果计算也是正确的。我只是得到这个例外。有什么想法吗?
从Java 5开始,有一个新的(不是很新的)包:java.util.concurrent
。在这个包中有很多工具可以让你在使用多线程时变得简单。特别是有几个选项可以获得开箱即用的线程池。请看Executors class API和ExecutorService class API。阅读可用的ExecutorService的各种实现。它需要一些习惯,但是一旦你掌握了这个概念,就会消除线程管理的所有繁琐工作,而你所要做的就是担心你的实现逻辑。它也使你的代码更简单,更清洁。
如果你将寻找到Thread.class你会看到下面的代码:
public Thread(ThreadGroup group, Runnable target) {
init(group, target, "Thread-" + nextThreadNum(), 0);
}
/* For autonumbering anonymous threads. */
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
因此,大家可以看到,每次你创建新的线程,它有一个使用静态字段threadInitNumber
创造的唯一名称 - 记住静态字段在给定类的所有实例中共享。
你的threadCount=4
意味着你将一次创建4个线程,但你做了几次,3次是准确的,3次4次等于12次 - 这就是在你看来创建“鬼”线程的原因。您正在创建12个线程而不是4个,但不是一次。现在为什么thre线程被命名为13,保证12?那么因为其他应用程序必须在调用之前创建了新线程generateCoordinatesMultiThread
请指出whith行引发异常 - 标记'WordMapper.java:21' – Antoniossss
是什么让您认为theads是虚线?如果是线程号,请注意这个数字只是一个增加的静态int,例如,如果您重新运行该方法,数字会更大(并且线程1可能是主线程,所以应该将4个新线程命名为Thread -2到Thread-5)。如果您希望线程在调用该方法时具有相同的名称,请为该构造函数提供一个名称。 – Thomas
@SirTobiSwobi,但说实话,使用ExecutorService和Callable任务会更简单。 – Antoniossss