簡體   English   中英

Java:線程不起作用

[英]Java: Thread doesn't work

我正在嘗試在for循環中啟動線程。 該任務僅需等待一秒鍾(Thread.sleep()),因此,每次循環重新開始時,都會啟動一個新線程,並且該線程應使該線程之后的代碼等待執行。

public void count()
{
    for(int i = 29; i>=0; i--)
    {
        Thread t1;
        t1 = new Thread(new TimerClass());
        t1.start();
        String s = String.valueOf(i); 
        jLabel6.setText(s);
        System.out.println(s);
    }
}


public class TimerClass implements Runnable{

   @Override
   public void run()
   {
       try{
           Thread.sleep(1000);
           System.out.println("Timer");
       } catch(InterruptedException e)
       {
       }
   }
}

如您所見,我在兩個方法System.out.println()中都實現了它們,以檢查它們是否實際執行。 我得到這個:

29
28
27
26
...//25 - 3
2
1
0
Timer
Timer
Timer
//in all 29 times Timer

因此應該是29,Timer,28,Timer等,但事實並非如此。 有人知道代碼有什么問題嗎? 非常感謝。

您正在啟動線程的主循環可能會占據CPU的主導地位,因此它完成了整個循環,然后線程才有機會離開。

實際上,考慮到所有線程都睡了一秒鍾,而您只循環了29次,因此可以確保循環將在線程執行之前完成(並打印所有數字)。 如果要打印線程,請在主循環中添加睡眠-請記住,啟動線程時主循環不會停止。

您可以將一個線程加入主線程,這樣您的線程將先完成,然后再進入主線程

public void count()
{
    for(int i = 29; i>=0; i--)
    {
        Thread t1;
        t1 = new Thread(new TimerClass());
        t1.start();
        t1.join();
        String s = String.valueOf(i); 
        jLabel6.setText(s);
        System.out.println(s);
    }
}

這是我產生2個線程或一個線程的代碼,它取決於arrayList的大小,但是在我的情況下,該線程正在執行更復雜的任務,然后等待1秒鍾

for (int i = 0; i < array.size(); i += 2) {
            Thread t1 = null;
            Thread t2 = null;

            if (i < array.size() - 1 && array.size() > 1) {

                t1 = new Thread(array.get(i));
                t2 = new Thread(array.get(i + 1));
                t1.start();
                t2.start();

            }

            else {

                t2 = new Thread(array.get(i));

                t2.start();
            }
            if (t1 != null)
                t1.join();
            if (t2 != null)
                t2.join();
              }

在我的代碼中,用實現Runnable接口的對象填充arrayList。

即使您將線程休眠1毫秒,您的結果也將相同。 如果您可以管理線程休眠的時間少於打印結果所花費的時間,則結果可能與預期的一樣。 這是我的代碼,我將時間設置為1 ms,但結果卻是相同的。

public class MultiThreading implements Runnable
{
       public void run()
       {
           try
           {
               Thread.sleep(1);
               System.out.println("Timer");
           } 
           catch(Exception e)
           {

           }
       }

    public static void main(String [] args)
    {
        for(int i = 29; i>=0; i--)
        {
            Thread t1;
            t1 = new Thread(new MultiThreading());
            t1.start();
            String s = String.valueOf(i); 
            System.out.println(s);
        }
     }
}

如果您注釋掉Thread.sleep(1)方法,則結果將與預期的一樣。

延遲足以讓count()中的for循環在可以從線程打印“計時器”之前完成。

發生的事情是,您啟動的線程開始執行並立即進入睡眠狀態。 同時,您的循環不斷運行。 因為線程的全部要點是它們異步運行,所以我不太了解為什么您認為您的主循環應該等待它完成睡眠。 該線程已開始運行,並且現在獨立於主循環運行。

如果要等待剛開始完成的線程(在這種情況下,您也可以使用一種方法),請使用同步原語之一,即Thread.wait()

您實際要做的是在另一個線程運行時阻塞您的主線程。 請不要使用Thread#sleep語句,因為它們不可靠,無法“使您的應用程序正常工作”。 您要使用的是Thread#join。 有關示例,請參見dharr的代碼。

同樣,在創建線程或運行異步任務時最好使用ExecutorsExecutorServices

線程很有趣。 將虛擬線程視為物理線程。 您穿的衣服上有很多線,所有線都同時工作以將襯衫固定在一起。 在虛擬方面有什么Thread.start()的作用是啟動一個線程在不同的鏈,而下面的代碼繼續執行(即兩個線程同時工作,像2名選手下次運行到對方)。 考慮在Thread.start()之后放置一個斷點。 你會明白的。

為了達到理想的效果,只需將Thread.sleep()放入主循環即可。 這將導致輸出

29
Timer
28
Timer
// etc.

希望這會有所幫助。

Jarod。

另一個類似於襯衫中的線的類比:

將線程視為主程序的協作者(線程本身)。 如果啟動線程,則將一些工作交給此同事。 該同事回到他的辦公室從事這項工作。 您還將繼續執行任務。

這就是為什么數字將在第一個線程/同事輸出anythig之前出現的原因。 在他完成任務之前,您已經完成了任務(將工作分發給其他同事)。

如果要分發一些工作然后等待完成,請按照其他人的建議使用t1.join()。 但是,如果執行此操作,則創建新的線程是沒有意義的,因為您(似乎)不想(與許多同事)以特定的順序並行處理某些事情-您可以自己進行處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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