![](/img/trans.png)
[英]What is the difference between Thread.start() and Thread.run()?
[英]Thread.start() doesn't call Thread.run() method
在我的項目中,有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方法中,有sleep(500),但結果只是出現在控制台中,沒有任何睡眠。
我將不勝感激,因為我已經花了太多時間在此方面,但不幸的是未能解決問題。
這里發生的幾件事會使您感到困惑。 讓我們從一個不明顯的東西開始:
System.out.print()
使用鎖定來確保線程不會相互打印。 因此,當您有兩個線程,一個線程打印foo
,另一個線程打印bar
,您可以獲取foobar
或barfoo
但不能fboaro
(=不混合)。
這也意味着當一個線程(主線程或三個計算線程之一)打印某些內容時,所有其他希望同時打印的線程也將等待。
下一步:啟動線程不會將它們排隊。 如果啟動N個線程,系統將同時運行它們的所有代碼。 如果他們都睡眠500毫秒,那么這種睡眠將並行進行。 如果希望線程按特定順序執行,則必須使用隊列和鎖。
最后:您啟動了線程,但從未等待結果。 因此,發生的事情是主線程啟動了線程,然后繼續(可能終止)。 然后,所有三個線程同時等待500毫秒,然后它們都嘗試計算結果並同時打印結果。
正如您可能開始理解的那樣,所有這些都是非常復雜且令人討厭的。 因此,Java 6引入了並發框架來解決許多此類問題。
簡而言之,不要再創建線程了。 創建Callables
返回您想要的結果的Callables
對象,然后將其提交給ExecutorService
。 該服務將運行它們並返回Future
。 然后,您可以查詢將來的結果。
這樣,您就不必處理低級線程問題,同步,鎖和隊列。
有關:
(編輯以允許刪除downvote。)
您的結果可能隱藏在最后一個字符串中:“ true2hi6falsetrue5hi2483falsehi720hi120”。 所有線程實際上執行命令:
System.out.print(NumbersOperations.getFactorial(number));
當循環結束時,他們必須等待0.5秒。 您還有一個print
方法來執行此操作,而不是println
,因此每個結果都“粘貼”到另一個結果上。 如注釋所示,線程不會單獨執行,它們不會等待,即前一個Thread
的結束。
您需要做的一件煩惱的事情是:等待線程完成。 我希望對Thread.join()
三個調用,否則您的程序可能會結束並中止線程(您確實將它們標記為守護程序,對嗎?),然后它們才能打印結果。
謝謝大家! 它幫助我更好地了解線程。 為了解決此問題,我使用了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();
}
}
和我的線程類,我沒有改變。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.