2014-08-28 5 views
5

मैं एक साधारण उद्देश्य के लिए एक छोटा सा जावा सर्वलेट बनाया: एक बार जब यह कहा जाता है, यह निम्न चरणों का पालन करना होगा: स्थानीय फाइल सिस्टम से जावा सर्वलेट में फ़ाइल एक्सेस को सिंक्रनाइज़ करने के लिए कैसे करें?

  • प्रक्रिया

    1. पढ़ें फ़ाइल foo.json फ़ाइल से डेटा और यह करने के लिए कुछ परिवर्तन करना
    2. फ़ाइल
    कोड की

    सरलीकृत संस्करण में परिवर्तन वापस लिखें:

    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        FileInputStream inputStream = new FileInputStream("foo.json"); 
        String filecontent = IOUtils.toString(inputStream); 
        inputStream.close(); 
    
        JSONObject json = new JSONObject(filecontent); 
    
        doSomeChangesTo(json); 
    
        FileWriter writer = new FileWriter("foo.json"); 
        writer.write(json.toJSONString()); 
        writer.flush(); 
        writer.close(); 
    } 
    

    अब मुझे समस्या का सामना करना पड़ रहा है कि ऐसा हो सकता है कि सर्वलेट को लगभग एक ही समय में सर्वलेट के लिए दो या दो से अधिक HTTP अनुरोधों द्वारा बुलाया जाता है। एक ही फ़ाइल पर एकाधिक समांतर लेखन पहुंच से बचने के लिए मुझे इसे किसी भी तरह सिंक्रनाइज़ करने की आवश्यकता है। सर्वलेट लाइफसाइकिल प्रक्रिया की मेरी समझ से, प्रत्येक अनुरोध एक नए धागे को जन्म देता है, इसलिए फ़ाइल लॉक का उपयोग करने से शायद कोई प्रभाव नहीं पड़ता:

    फ़ाइल लॉक पूरे जावा वर्चुअल मशीन की ओर से आयोजित किए जाते हैं। वे एक ही वर्चुअल मशीन के भीतर एकाधिक थ्रेड्स द्वारा फ़ाइल तक पहुंच को नियंत्रित करने के लिए उपयुक्त नहीं हैं।

    (http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileLock.html से)

    मुझे लगता है कि synchronized(){} कीवर्ड का उपयोग भी के बाद से मैं फाइल सिस्टम का उपयोग सिंक्रनाइज़ करने के लिए और चर/वस्तुओं के लिए पहुँच नहीं चाहता कार्य नहीं करेगा।

    तो, उस सर्वलेट पर एकाधिक समानांतर अनुरोध होने पर, मेरे सर्वलेट में फ़ाइल सिस्टम पहुंच को सिंक्रनाइज़ कैसे कर सकता है?

  • +0

    जबकि उस पर काम कर फ़ाइल का नाम बदलें ?मुझे लगता है कि फाइल के बजाए डीबी का उपयोग करना एक ऐसा निर्णय नहीं है जो आपके ऊपर है? – Fildor

    +0

    यदि आपका ऐप फ़ाइल को लिखने वाला एकमात्र है (और क्लस्टर्ड नहीं है), सिंकोननाइज़ेशन ठीक काम करेगा। लोग आमतौर पर एक डेटाबेस का उपयोग करते हैं जो आपके लिए समवर्ती पहुंच को संभालता है। –

    +0

    क्या * बिल्कुल * आप यहां सिंक्रनाइज़ करने की कोशिश कर रहे हैं? क्या यह पढ़ने-प्रक्रिया-लिखने की पूरी प्रक्रिया है? या क्या यह व्यक्ति पढ़ता है और लिखता है, जबकि प्रसंस्करण intertwine (और आप पुराने पढ़ने से डेटा वापस लिख सकते हैं)? – Ordous

    उत्तर

    6

    मुझे लगता है कि synchronized(){} कीवर्ड का उपयोग भी के बाद से मैं फाइल सिस्टम का उपयोग सिंक्रनाइज़ करने के लिए और चर/वस्तुओं के लिए पहुँच नहीं चाहता कार्य नहीं करेगा।

    synchronized का उपयोग कर काम कर सकते हैं। आप मान रहे हैं कि यदि आप एकाधिक थ्रेड से ऑब्जेक्ट एक्स तक पहुंच को नियंत्रित करना चाहते हैं, तो आपको उस ऑब्जेक्ट पर synchronized का उपयोग करना होगा। आप नहीं करते आप पर ऑब्जेक्ट पर उपयोग कर सकते हैं, बशर्ते सभी एक्सेस एक ही ऑब्जेक्ट का उपयोग करें।

    वास्तव में, यह अक्सर बेहतर, तुल्यकालन के लिए एक अलग private ताला वस्तु का उपयोग करने के क्योंकि यह वर्ग के बाहर कोड के लिए तो असंभव है ताला पर सिंक्रनाइज़ करने के लिए है।

    public class SharedFile 
    { 
         private final File path; 
         private final Object lock = new Object(); 
    
         public SharedFile(File path) { 
         this.path = path; 
         } 
    
         public void process(.....) throws IOException { 
         synchronized(lock) { 
          try(InputStream = new FileInputStream(path)) { 
           .... 
          } 
         } 
         } 
    } 
    
    +0

    में फ़ाइल तक पहुंचने वाले कोड को लपेटें, नहीं, लॉक ऑब्जेक्ट यहां महत्वपूर्ण है – mavroprovato

    3

    आप एक Semaphore उपयोग कर सकते हैं इस प्रकार है,:

    तो, आप प्रत्येक साझा फ़ाइल के लिए कुछ इस तरह, एक उदाहरण के साथ हो सकता है

    private static Semaphore semaphore = new Semaphore(1); 
    
    public void doSomeChangesTo(JSONObject json) { 
        try { 
         semaphore.acquire(); 
    
         // doSomeChangesTo 
    
        } finally { 
         semaphore.release(); 
        } 
    } 
    
    +0

    संपादन के लिए धन्यवाद @ bcsb1001 – troig

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