2012-08-31 39 views
4

我正在嘗試編寫一個監視阻止操作需要多長時間的線程。例如,我有一個阻擊戰是這樣的:監視阻止操作

class BlockingThread extends Thread{ 

    public volatile boolean success = false; 
    public volatile long startedTime = 0; 

    public void run(){ 

     startedTime = System.currentTimeMillis(); 
     success = doBlockingAction(); //no idea how long this action will take 
    } 

} 

,我希望有另一個線程基本上都會叫「超時」功能,如果阻擊戰時間過長:

class MonitorThread extends Thread{ 

    public void run(){ 
     while(System.currentTimeMillis() - blockingThread.startedTime > TIMEOUT_DURATION) 
     { 
     ..keep waiting until the time runs out.. 
     } 

     if(!blockingThread.success){ 
     listener.timeout(); 
     //Took too long. 
     } 
    } 

} 

我無法理解如何確保BlockingThread實際上處於阻塞操作中,而我正在測量MonitorThread中的時間。

如果我做這樣的事情,

Thread blockingThread = new BlockingThread(); 
blockingThread.start(); 
Thread monitorThread = new MonitorThread(); 
monitorThread.start(); 

也不能保證一個線程實際開始運行之前,其他的代碼,所以我現在有沒有辦法知道,如果我的超時線程實際上正確測量阻止行爲的時間。我假設答案與鎖定和wait ing有關,但我無法弄清楚。

+0

我希望你的意思是'類BlockingThread'和'類MonitorThread'。 – Jeffrey

+0

SO上有一個[question](http://stackoverflow.com/q/2275443/960195)專門用於超時方法執行。這可能會有所幫助。 –

+0

@Jeffrey哈哈,哎呀。謝謝你的收穫。 – you786

回答

4

我可以建議你用類java.util.concurrent.ThreadPoolExecutor重寫你的代碼。 這個班級有很好的方法awaitTermination(),我想,這正是你需要的。

編輯:

這裏是你的BlockingThread,跑10秒,監控器,等待5秒:能

package sample.threadexecutor; 

import java.text.SimpleDateFormat; 
import java.util.Date; 

public class BlockingThread implements Runnable{ 

    public boolean succsess = false; 
    @Override 
    public void run() { 
     SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss.SSS"); 
     System.out.println(df.format(new Date()) + " start"); 
     try { 
      Thread.sleep(10000L); 
     } catch (InterruptedException e) { 
      System.out.println(df.format(new Date()) + " interrupted"); 
      succsess = false; 
      return; 
     } 
     System.out.println(df.format(new Date()) + " end"); 
     succsess = true; 
    } 
} 

和主要功能與執行:

package sample.threadexecutor; 

import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

public class main { 

    public static void main(String[] args) { 
     SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss.SSS"); 
     ExecutorService service= Executors.newSingleThreadExecutor(); 
     service.submit(new BlockingThread()); 
     try { 
      service.shutdown(); 
      if(service.awaitTermination(5, TimeUnit.SECONDS)){ 
       System.out.println(df.format(new Date()) + " execution completed"); 
      }else{ 
       System.out.println(df.format(new Date()) + " execution timeout"); 
      } 
     } catch (InterruptedException e) { 
      System.out.println(df.format(new Date()) + " monitoring interrupted"); 
     } 

    } 
} 

輸出:

22:28:37.005 start 
22:28:42.006 execution timeout 
22:28:47.006 end 

如果我們將超時設置爲20秒,則輸出:

22:30:20.210 start 
22:30:30.213 end 
22:30:30.214 execution completed 
+0

對不起,我不明白這是如何解決我的問題。你可以說得更詳細點嗎? – you786

+0

我使用ThreadPoolExecutor添加了示例 – user1516873

0

您可能只需循環幾次,然後blockingThread.startingTime被初始化。

class MonitorThread extends Thread{ 

    public void run(){ 
     boolean weWantToKeepRunning = true; 

     // here is your new event loop 
     while(weWantToKeepRunning){ 

      if (blockingThread.startedTime != 0) && (System.currentTimeMillis() - blockingThread.startedTime > TIMEOUT_DURATION)&& (!blockingThread.success){ 

       listener.timeout(); // too long 
       weWantToKeepRunning = false; // quit this loop 

      } 
     } 
    } 
} 
0

doBlockingAction的確會做什麼? Java API中的大多數阻止操作都有允許設置超時的變體。使用超時變量是最準確的方法。