在我的项目中,有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),但结果只出现在控制台中,没有任何睡眠。
我会感激任何帮助,因为我已经花了太多时间在这些东西上,不幸的是没有解决问题。
答案 0 :(得分:5)
这里有一些事情会让你感到困惑。让我们从一些不明显的事情开始:
System.out.print()
使用锁定来确保线程不会相互打印。所以当你有两个线程,一个打印foo
而另一个打印bar
时,你可以获得foobar
或barfoo
,但绝不会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();
}
}
和我的线程类我没有改变。