2017-10-19 60 views
0

在我的主線程中,我通過HttpURLConnection向服務器發送了一些數據,然後我啓動一個timer定期執行一個TimerTask來檢查服務器的響應。當我得到預期的字符串時,我打電話給timer.cancel()。之後,主線程從timer開始的位置恢復。如何在主線程調用的TimerTask線程完成之前抑制主線程?

我想象以下用同樣的機制簡化代碼只是爲這個職位:

public class Test { 
    public static void main(String[] args) throws InterruptedException { 
     System.out.println("start"); 
     Timer timer = new Timer(); 
     TmTask timerTask = new TmTask(timer);  
     Thread thread = new Thread(timerTask,"thread_1"); 
     thread.start(); 
     thread.join();  
     System.out.println("end"); 
    } 
} 

class TmTask extends TimerTask{ 
    Timer t; 

    public TmTask(Timer t){ 
     this.t = t; 
    } 

    @Override 
    public void run() { 
     t.schedule(new A(t), 100, 1000); 

    } 
} 
class A extends TimerTask{ 
    private Timer t; 
    private int i = 0; 
    public A(Timer t) { 
     this.t = t; 
    } 
    @Override 
    public void run() { 
     System.out.println("abc"); 
     i++; 
     if (i == 3) t.cancel(); 
    } 
} 

我的厚望是:

start 
abc 
abc 
abc 
end 

,但我得到:

start 
end 
abc 
abc 
abc 

最後我意識到在我的代碼中有3個線程創建,但我期望2(主線程和計時器線程)和join()方法在名爲thread_1的線程上工作,而不是定時器線程。但我不知道如何改進它。

任何人都可以幫助我嗎?提前致謝。

+0

爲什麼你想再次使用該線程?當你在主線程中等待它時,你可以在主線程上執行它... – Lino

+0

這會打破線程的想法。你想使用線程進行異步工作。你想要做的是強制它回到同步。 –

+0

在任何情況下,TimerTask都不應包含對Timer的引用。任務*是背景工作;它不應該*開始*其他後臺工作。 – VGR

回答

1

創建新線程的全部目的是從主線程中分別啓動它 - 以獲得並行執行。你有3個線程,因爲timertask創建了自己的線程。如果你希望你的當前(主)線程停止並等待結果,那麼你可以這樣做:

boolean result = false; 
while(! result) { 
result=checkForResult(); 
Thread.sleep(1000); 
} 

這將暫停當前線程,並使其阻塞。通常對於這樣的外部任務和異步調用,您不希望主線程停止執行並等待,因爲您不知道何時會得到結果,並且可能無限期地等待。所以你的結果可能是你想要的結果? :)

+0

我只是建議拋棄整個想法,等待開始,只是在主線上執行所有的事情,或者我想錯了? – Lino

+0

是的,這就是我想說的。如果你想要你的主線程等待你不需要額外的線程。線程的想法是與主線程並行運行。 –

+0

但是,阻止並行運行並不等待的任務可能是正確的選擇 - 然後他所做的是正確的,他想做的是錯誤的;) –

相關問題