2010-09-02 16 views
11

मैं जानना चाहता हूं कि जावा मैन्युअल रीसेट इवेंट और वेटहैंडल के .NET के वर्गों के समतुल्य प्रदान करता है, क्योंकि मैं एक कोड टाइम लिखना चाहता हूं जो एक ईवेंट ट्रिगर होने तक दिए गए टाइमआउट के लिए ब्लॉक करता है।जावा के समतुल्य .NET के मैनुअल रीसेट इवेंट और वेटहैंडल

WaitHandle और ManualResetEvent के नेट वर्गों है कि जो भी धागे की सुरक्षित रूप तक मुझे पता है है के लिए एक अच्छी, परेशानी से मुक्त इंटरफेस प्रदान, तो क्या जावा के लिए प्रस्ताव दिया है?

उत्तर

14

आप wait/notify (Monitor.Wait के बराबर और Monitor.Pulse) के बजाय का उपयोग कर विचार किया है?

आप यह देखने के लिए थोड़ा सा जांच करना चाहते हैं कि वास्तव में को की आवश्यकता है (दौड़ की स्थिति से बचने के लिए) लेकिन इसे काम करना चाहिए।

अन्यथा, CountDownLatch जैसे कुछ भी आप जो चाहते हैं वह कर सकते हैं।

संपादित करें: मैंने केवल यह देखा है कि CountDownLatch मूल रूप से "एकल उपयोग" है - आप बाद में गिनती को रीसेट नहीं कर सकते, जहां तक ​​मैं देख सकता हूं। आप इसके बजाय Semaphore चाह सकते हैं। समय समाप्त के साथ प्रतीक्षा करने के लिए tryAcquire इस तरह का उपयोग करें:

if (semaphore.tryAquire(5, TimeUnit.SECONDS)) { 
    ... 
    // Permit was granted before timeout 
} else { 
    // We timed out while waiting 
} 

ध्यान दें कि यह ManualResetEvent के विपरीत है कि tryAcquire करने के लिए प्रत्येक सफल कॉल परमिट की संख्या कम हो जाएगा - तो अंततः वे फिर से बाहर चलाने के लिए होगा। आप इसे ManualResetEvent के साथ स्थायी रूप से "सेट" नहीं कर सकते हैं। (यह CountdownLatch के साथ काम करेंगे, लेकिन फिर तुम नहीं "रीसेट" हो सकता है यह :)

+0

लेकिन टाइमआउट पहलू के बारे में क्या? काउंटरडाउनलैच के दस्तावेज़ में मैंने जो पढ़ा है, उससे ऐसा लगता है कि टाइमआउट मान नहीं है जिसे मैं अंतराल के अंत तक चलने से पहले रोक या रोक सकता हूं। मैं एक जावा टाइप करना चाहता हूं जिसका उपयोग मैं टाइमआउट के लिए प्रतीक्षा करने के लिए कर सकता हूं, और मैन्युअल ओवरराइड की तरह टाइमआउट खत्म होने से पहले इसे अवरुद्ध किया जा सकता है। इसके अलावा, हैलो श्री स्कीट! आप कैसे हैं? आपको शायद यह बहुत कुछ मिल जाए, लेकिन आपकी पुस्तक बहुत बढ़िया है! – Orca

+0

@ वोल्टनेट: आप 'प्रतीक्षा (लंबी टाइमआउट, टाइमयूनीट यूनिट)' कॉल करेंगे - जो दी गई टाइमआउट अवधि के लिए अवरुद्ध होगा * या * अगर लौच 0 पर गिना जाता है तो पहले वापस लौटें। आपको खुशी है कि आपको पुस्तक पसंद है :) –

+0

Yup , समाधान को खूबसूरती से काम करना चाहिए क्योंकि मेरे पास केवल एक वस्तु है जो किसी भी समय प्रतीक्षा कर रही है। धन्यवाद, श्री जॉन स्कीट। – Orca

2

से: http://www.experts-exchange.com/Programming/Languages/Java/Q_22076798.html

हाय, आप java.util.concurrent.Semaphore वर्ग का उपयोग कर तुल्यकालन प्राप्त कर सकते हैं (उपयोग 0 परमिट)। नीचे

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Semaphore.html

उदाहरण कैसे पहले समन्वयन समस्या का समाधान करने के लिए आप पता चलता है, अन्य इसी तरह के हो जाएगा:

import java.util.concurrent.Semaphore; 

class ScalesCommunication { 

    private static Semaphore sem = new Semaphore(0); 

    // called by thread 1 
    void readLoop() { 
     //... 

     //after connection established, release semaphore (value incremented by 1) 
     sem.release(); 
    } 

    // called by thread 2 
    String sendCommand(String command) { 

     sem.acquire(); // thread waits here if sem value == 0 

     // at this point connection is established 
     //... 
    } 
} 
4
class ManualResetEvent { 

    private final Object monitor = new Object(); 
    private volatile boolean open = false; 

    public ManualResetEvent(boolean open) { 
    this.open = open; 
    } 

    public void waitOne() throws InterruptedException { 
    synchronized (monitor) { 
     while (open==false) { 
      monitor.wait(); 
     } 
    } 
    } 

    public void set() {//open start 
    synchronized (monitor) { 
     open = true; 
     monitor.notifyAll(); 
    } 
    } 

    public void reset() {//close stop 
    open = false; 
    } 
} 
+0

ध्यान दें कि इसमें एक बुरा बग है: यदि 'सेट() 'से पहले' प्रतीक्षा करें ') को कॉल किया जाता है तो' मॉनिटर 'दर्ज किया जाएगा और इसलिए' सेट() 'पर कॉल अवरुद्ध हो जाएगा, जिसके परिणामस्वरूप डेडलॉक होगा। मेरा हैकी समाधान 'लूप में' monitor.wait (10) 'को कॉल करना था जो हर पुनरावृत्ति को सिंक्रनाइज़ेशन से बाहर करता है। –

+0

दरअसल, मैं इसके बारे में गलत हो सकता हूं क्योंकि स्पष्ट रूप से मॉनिटर प्रतीक्षा के दौरान जारी किया जाना चाहिए, हालांकि मेरे परीक्षणों ने निश्चित डेडलॉक दिखाया। भले ही, मैंने अपने उपयोग के मामले के लिए 'सेमफोर' का उपयोग करने के लिए स्विच किया है। –

+0

क्या आप डेडलॉक के साथ परीक्षण कर सकते हैं? – user249654

1

सिद्धांत रूप में, ManualResetEvent वर्ग के रूप में ऊपर दी गई जावा पर सही है 5 (लेकिन पहले नहीं)। अस्थिर के गलत (या अपर्याप्त) कार्यान्वयन के लंबे इतिहास को देखते हुए, मुझे गारंटीकृत लिखने की बाधा उत्पन्न करने के लिए रीसेट() में एक अतिरिक्त सिंक्रनाइज़ ब्लॉक जोड़ने के लिए बुद्धिमान लगता है, और पूर्ण परमाणु सुनिश्चित करता है। खतरा यह है कि "ओपन" का एक पठन बहु-प्रोसेसर इंटेल सीपीयू पर "खुला" लिख सकता है। नीचे दिए गए परिवर्तन का लाभ: यह अनुकूल रूप से कुशल नहीं हो सकता है, लेकिन बहुत कम अतिरिक्त लागत पर, गलत होने की गारंटी होने का इसका बड़ा लाभ है।

class ManualResetEvent { 
     private final Object monitor = new Object(); 
     private volatile boolean open = false; 

     public ManualResetEvent(boolean open) { 
     this.open = open; } 

     public void waitOne() throws InterruptedException { 
     synchronized (monitor) { 
      while (open==false) { 
       monitor.wait(); 
      } 
     } 
     } 

     public void set() {//open start 
     synchronized (monitor) { 
      open = true; 
      monitor.notifyAll(); 
     } 
     } 

     public void reset() {//close stop 
     synchronized(monitor) { 
      open = false; 
     } 
     } 
    } 

मूल पोस्टर के लिए धन्यवाद।

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