首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java产卵鬼线

Java产卵鬼线
EN

Stack Overflow用户
提问于 2016-09-28 15:10:14
回答 2查看 237关注 0票数 0

我正在研究一种新的NLP分类算法,并希望使它成为多线程。我的实现正确地执行了它应该做的事情,但是在使用threads=4运行时我会得到一些奇怪的异常。

代码语言:javascript
复制
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());
    }
}

这给了我一些例外:

线程"Thread-5“java.lang.NullPointerException中的异常 在semanticobjects.WordMapper.run(WordMapper.java:21) 在java.lang.Thread.run(Thread.java:695)

与9和13相同。这两个数字都是在使用threads=4运行时不应该首先生成的数字。结果也是正确的。我只是得到了这个例外。有什么想法吗?

EN

回答 2

Stack Overflow用户

发布于 2016-09-28 15:28:36

从Java 5开始,有一个新的(不太新的)包:java.util.concurrent。在这个包中,有很多工具可以使你的生活变得更简单,当你使用多线程时。特别是有几个选项可以得到一个开箱即用的线程池。看看遗嘱执行人类API和ExecutorService类API。了解可用的ExecutorService的各种实现。这需要一些习惯,但是一旦您掌握了这个概念,它就会消除线程管理的所有繁琐工作,而您所要做的就是担心您的实现逻辑。它还使您的代码更简单、更简洁。

票数 0
EN

Stack Overflow用户

发布于 2016-09-28 15:30:16

如果您查看Thread.class,您将看到以下代码:

代码语言:javascript
复制
    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次,而3x4等于12 --这就是在您看来创建“鬼”线程的原因。您正在创建12个线程,不是4个,而是一次创建。那么为什么这个线程被命名为13而不是12呢?因为应用程序的其他部分必须在调用generateCoordinatesMultiThread之前创建了新线程。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39751373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档