Thread.start()不调用Thread.run()方法

时间:2013-08-29 13:51:56

标签: java

在我的项目中,有3个类扩展了Thread,每个类都对整数进行了一些计算。我需要运行它们来获取所有三个计算值。需要对特定范围内的所有整数执行此过程。

这是我的一个主题:

public class FactorialNumber extends Thread {
private int number;

public void setNumber(int number) {
    this.number = number;
}

public void run() {
    try {
        sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace(); 
    }
    System.out.print(NumbersOperations.getFactorial(number));
}
}

这是一个尝试启动线程的方法:

public static void getThreevalues() throws InterruptedException {
    int startOfRange = getBorder("Enter the left border of range: ");
    int endOfRange = getBorder("Enter the right border of range: ");
    for(int i = startOfRange; i <= endOfRange; i++) {
        PrimeNumber primeNumber = new PrimeNumber();
        FibonachiNumber fibonachiNumber = new FibonachiNumber();
        FactorialNumber factorialNumber = new FactorialNumber();
        primeNumber.setNumber(i);
        fibonachiNumber.setNumber(i);
        factorialNumber.setNumber(i);
        System.out.print("Number: " + i);
        System.out.print(" is prime number ");
        primeNumber.start();
        System.out.print(". Fibonachi - " );
        fibonachiNumber.start();
        System.out.print(". Factorial - ");
        factorialNumber.start();
        System.out.println();

    }
}

运行我的代码后,我得到了这个:

Number: 3 is prime number . Fibonachi - . Factorial - 
Number: 4 is prime number . Fibonachi - . Factorial - 
Number: 5 is prime number . Fibonachi - . Factorial - 
Number: 6 is prime number . Fibonachi - . Factorial - 
true2hi6falsetrue5hi2483falsehi720hi120

据我所知,start()不会调用run()方法。在我的run方法中有睡眠(500),但结果只出现在控制台中,没有任何睡眠。

我会感激任何帮助,因为我已经花了太多时间在这些东西上,不幸的是没有解决问题。

4 个答案:

答案 0 :(得分:5)

这里有一些事情会让你感到困惑。让我们从一些不明显的事情开始:

System.out.print()使用锁定来确保线程不会相互打印。所以当你有两个线程,一个打印foo而另一个打印bar时,你可以获得foobarbarfoo,但绝不会fboaro(=没有混合)。

这也意味着当一个线程(三个计算线程中的主线程或一个线程)打印出某些东西时,所有其他想要同时打印的线程都会等待。

下一步:启动线程不会对它们进行排队。如果启动N个线程,系统将同时运行它们的所有代码。如果他们都睡了500毫秒,那么这种睡眠就会平行。如果希望线程按特定顺序执行,则必须使用队列和锁。

最后:你启动线程,但你永远不会等待结果。所以会发生什么是主线程启动线程然后继续(可能终止)。然后所有三个线程同时等待500ms,然后他们都尝试计算结果并同时打印它。

正如您可能已经开始理解的那样,所有这些都非常复杂且烦人。这就是为什么Java 6引入了解决许多这些问题的并发框架。

简而言之,不要再创建线程了。创建返回所需结果的Callables,然后将其提交给ExecutorService。该服务将运行它们并返回Future s。然后,您可以查询结果的未来。

这样,您就不必处理低级线程问题,同步,锁和队列。

相关:

(编辑以允许删除downvote。)

答案 1 :(得分:0)

您的结果可能隐藏在最后一个字符串中:“true2hi6falsetrue5hi2483falsehi720hi120”。所有线程实际执行命令:

System.out.print(NumbersOperations.getFactorial(number)); 

当循环结束时,他们必须等待0.5秒。您还有一个print方法来执行此操作,而不是println,因此每个结果都“贴在”另一个上。正如评论所指出的那样,线程不会单独排除,它们不会等待前一个Thread的结束。

答案 2 :(得分:0)

你需要做的一件事:等待线程完成。我希望三次调用Thread.join()否则你的程序可能会结束并中止线程(你确实将它们标记为守护进程,对吗?)然后才能打印结果。

答案 3 :(得分:0)

谢谢大家!它帮助我更好地理解线程。为了解决这个问题,我使用了方法join(),所以现在启动线程的方法如下所示:

public static void getThreevalues() throws InterruptedException {
    int startOfRange = getBorder("Enter the left border of range: ");
    int endOfRange = getBorder("Enter the right border of range: ");
    for(int i = startOfRange; i <= endOfRange; i++) {
        PrimeNumber primeNumber = new PrimeNumber();
        FibonachiNumber fibonachiNumber = new FibonachiNumber();
        FactorialNumber factorialNumber = new FactorialNumber();
        primeNumber.setNumber(i);
        fibonachiNumber.setNumber(i);
        factorialNumber.setNumber(i);
        System.out.print("Number: " + i);
        primeNumber.start();
        primeNumber.join();
        fibonachiNumber.start();
        fibonachiNumber.join();
        factorialNumber.start();
        factorialNumber.join();
        Thread.sleep(2000); // this line's useful to present result by lines
        System.out.println();
    }
}

和我的线程类我没有改变。