簡體   English   中英

Thread.start()不調用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 ,您可以獲取foobarbarfoo但不能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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM