[英]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的代碼。
同樣,在創建線程或運行異步任務時最好使用Executors和ExecutorServices 。
線程很有趣。 將虛擬線程視為物理線程。 您穿的衣服上有很多線,所有線都同時工作以將襯衫固定在一起。 在虛擬方面有什么Thread.start()
的作用是啟動一個線程在不同的鏈,而下面的代碼繼續執行(即兩個線程同時工作,像2名選手下次運行到對方)。 考慮在Thread.start()
之后放置一個斷點。 你會明白的。
為了達到理想的效果,只需將Thread.sleep()
放入主循環即可。 這將導致輸出
29
Timer
28
Timer
// etc.
希望這會有所幫助。
Jarod。
另一個類似於襯衫中的線的類比:
將線程視為主程序的協作者(線程本身)。 如果啟動線程,則將一些工作交給此同事。 該同事回到他的辦公室從事這項工作。 您還將繼續執行任務。
這就是為什么數字將在第一個線程/同事輸出anythig之前出現的原因。 在他完成任務之前,您已經完成了任務(將工作分發給其他同事)。
如果要分發一些工作然后等待完成,請按照其他人的建議使用t1.join()。 但是,如果執行此操作,則創建新的線程是沒有意義的,因為您(似乎)不想(與許多同事)以特定的順序並行處理某些事情-您可以自己進行處理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.