2012-12-03 15 views
6

मैं भविष्य कंप्यूटिंग कर रहा हूँ की समय समाप्ति को रोकने के लिए धारावाहिक बंदरगाह।कैसे हुआ करने के लिए एक धारावाहिक घटना के लिए इंतजार में समय समाप्त होने के लिए एक भविष्य

समस्या यह है कि सीरियल पोर्ट से पढ़ने अपेक्षाकृत धीमी है और यहां तक ​​कि जब एक धारावाहिक घटना हो रही है तो समय समाप्त हो जाता है और TimeoutException फेंक दिया जाता है। एक धारावाहिक घटना होने पर मैं अपने भविष्य की टाइमआउट घड़ी को रोकने के लिए क्या कर सकता हूं?

मैं एक AtomicReference साथ यह कोशिश की, लेकिन है कि कुछ भी नहीं बदला:

public class CommunicationTask implements Callable<Response>, Observer { 
    private AtomicReference atomicResponse = new AtomicReference(new Response("timeout")); 
    private CountDownLatch latch = new CountDownLatch(1); 
    private SerialPort port; 

    CommunicationTask(SerialCommunicator communicator, Request request) { 
    this.communicator = communicator; 
    this.message = request.serialize(); 
    this.port = communicator.getPort(); 
    } 

    @Override 
    public Response call() throws Exception { 
    return query(message); 
    } 

    public Response query(String message) { 
    communicator.getListener().addObserver(this); 
    message = message + "\r\n"; 
    try { 
     port.writeString(message); 
    } catch (Exception e) { 
     log.warn("Could not write to port: " + e); 
     communicator.disconnect(); 
    } 
    try { 
     latch.await(); 
    } catch (InterruptedException e) { 
     log.info("Execution time out."); 
    } 
    communicator.getListener().deleteObserver(this); 
    return (Response)atomicResponse.get(); 
    } 

    @Override 
    public void update(Observable o, Object arg) { 
    atomicResponse.set((Response)arg); 
    latch.countDown(); 
    } 
} 

मैं इस समस्या को हल करने के लिए क्या कर सकते हैं?

संपादित करें:

ठीक है मुझे एक त्रुटि थी। मैं अपने update फ़ंक्शन में atomicResponse को सेट करने के लिए अपने लच को गिन रहा था। अब यह काम करता प्रतीत होता है, लेकिन अभी भी सवाल है यदि ऐसा दृष्टिकोण ऐसा करने का सही तरीका है?

+0

आप करने के लिए एक 'isCommunicationStarted' विधि जोड़ सकते हैं का पता लगाया है आपके संचार टास्क - जब आप 'टाइमआउट एक्सेप्शन' पकड़ते हैं, तो 'कम्युनिकेशन स्टार्टेड' की जांच करें - अगर यह गलत => रद्द हो जाता है, अन्यथा 'future.get() 'फिर से प्रयास करें (शायद एक नया टाइमआउट के साथ)। – assylias

+0

क्या आप अपनी टास्क क्लास को दो में विभाजित कर सकते हैं: पहली बार ईवेंट टाइमआउट के साथ शुरू होने तक प्रतीक्षा करेगा और ईवेंट की शुरुआत पर दूसरे प्रकार के कार्य को सबमिट करेगा। दूसरा कार्य तदनुसार घटना को संसाधित करेगा। –

+0

यह स्पष्ट नहीं है कि आप क्या हासिल करना चाहते हैं। टाइमआउट सेट करने का तात्पर्य है कि टाइमआउट के बाद आने वाली घटनाओं को अनदेखा किया जा सकता है। यदि हां, सवाल में कोने का मामला क्यों मायने रखता है? – axtavt

उत्तर

0

आशा है कि इससे मदद मिलेगी। मैं उम्मीदों पर इस पर टिप्पणी नहीं करूंगा कि कोड से सब कुछ स्पष्ट है।

class CommunicationTask implements Callable<String>, Observer { 
    volatile boolean ignoreTimeoutException; 

    public CommunicationTask(SerialCommunicator communicator, Request request) { 
    } 

    public String call() throws Exception { 
     Thread.sleep(1000); 
     return "done"; 
    } 

    public void update(Observable o, Object arg) { 
     ignoreTimeoutException = true; 
    } 
} 

class FutureCommunicationTask extends FutureTask<String> { 
    private CommunicationTask ct; 

    public FutureCommunicationTask(CommunicationTask ct) { 
     super(ct); 
     this.ct = ct; 
    } 

    public String get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { 
     try { 
      return super.get(timeout, unit); 
     } catch (TimeoutException e) { 
      if (ct.ignoreTimeoutException) { 
       return get(); // no timeout wait 
      } 
      throw e; 
     } 
    } 
} 

public class Test { 

    public static void main(String[] args) throws Exception { 
     CommunicationTask ct = new CommunicationTask(null, null); 
     FutureTask<String> fct = new FutureCommunicationTask(ct); 
     ExecutorService ex = Executors.newSingleThreadExecutor(); 
     ex.execute(fct); 
//  uncomment this line and timeout will be cancelled 
     ct.update(null, null); 
     String res = fct.get(1, TimeUnit.MILLISECONDS); 
     System.out.println(res); 
    } 
} 
1

आप गूगल के अमरूद 'भविष्य श्रोता', यह Async भविष्य पर आधारित है, कोड स्निपेट निम्नलिखित आशा है कि आप में मदद करता है ....

import java.util.concurrent.Callable; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

import com.google.common.util.concurrent.FutureCallback; 
import com.google.common.util.concurrent.Futures; 
import com.google.common.util.concurrent.ListenableFuture; 
import com.google.common.util.concurrent.ListeningExecutorService; 
import com.google.common.util.concurrent.MoreExecutors; 

public class SyncFutureExample { 
    public static void main(String[] args) { 
     ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1)); 
     ListenableFuture<String> lf = service.submit(new CommuncationTask()); 

     //no need for future.get() or future.get(10,time minutes) 


     //add callbacks(= async future listeners) .... 
     Futures.addCallback(lf, new FutureCallback<String>() { 
       public void onSuccess(String input) { 
       System.out.println(input + " >>> success");//gets a callback once task is success 
       } 
       public void onFailure(Throwable thrown) { 
        System.out.println(thrown + " >>> failure");//gets a callback if task is failed 
       } 
      }); 
     service.shutdown(); 
    } 

} 

class CommuncationTask implements Callable<String>{ 

    public String call() throws Exception { 
     TimeUnit.SECONDS.sleep(15);// some dummy serious task ............. 
     return "TaskDone"; 
    } 


} 
संबंधित मुद्दे

 संबंधित मुद्दे