2013-02-19 26 views
7

मैं ग्लासफिश पर एक RESTful जावा बैकएंड चल रहा हूँ। कि से जुड़ा हुआ है एक एचटीएमएल 5/जे एस दृश्यपटल जो मैं एक अलग स्थान पर एक webapp परियोजना में डाल सकते हैं (और फिर एक निर्भरता के रूप में बैकएंड शामिल हैं), या चलाने के एक आईआईएस वेबसर्वर पर। सीओआरएस कोई मुद्दा नहीं है। इस निम्नलिखित समस्या का हल जो कुछ भी:ThreadLocal सिंगलटन

स्थिति:

  1. User 1 पर लॉग करता है और डेटाबेस पथ डेटाबेस में 'db/user1 /'
  2. User 1 आवेषण 'वैल्यू 1' पर सेट है
  3. User 2 लॉग पर और डेटाबेस पथ पर सेट है 'db/user2 /'
  4. User 1 डेटाबेस से

User 1 नहीं होगा 'वैल्यू 1' को हटाना की कोशिश करता है के बाद से DatabasePath/user2 db से बदल दिया गया है और वहाँ है कि डेटाबेस में कोई मान 1 है, db/user1 से हटाने के लिए मान 1 में सक्षम।

public class DataAccess{ 
    private static DataAccess dataaccess; 
    private String databasepath; 

    public static DataAccess getInstance() { 
     if (dataaccess == null) { 
      dataaccess = new DataAccess(); 
     } 
    } 
} 

मैं getInstance() विधि को कैसे संशोधित कर सकता हूं ताकि यह सिंगलटन के रूप में कार्य करे, लेकिन केवल उस उपयोगकर्ता के थ्रेड के अंदर ही कार्य करता है? मैंने थ्रेडलोकल नामक कुछ देखा लेकिन इसे पूरी तरह से समझ में नहीं आया, क्या शायद यह एक समाधान है?

किसी भी मदद के सबसे निश्चित रूप से सराहनीय है।

+0

आपने 9 प्रश्न पूछे हैं, और 0 स्वीकार किए हैं। कृपया इसे सुधारें। – gaborsch

+0

मैं उत्तर कैसे स्वीकार करूं –

+0

एफएक्यू में इस अध्याय को पढ़ें, यहां तक ​​कि स्क्रीनशॉट भी हैं: http://stackoverflow.com/faq#howtoask – gaborsch

उत्तर

9

आप एक कारखाने पैटर्न में ThreadLocal वर्ग इस्तेमाल कर सकते हैं:

public class DataAccess{ 
    private static ThreadLocal<DataAccess> THREAD_LOCAL = new ThreadLocal() { 
    @Override 
    protected DataAccess initialValue() { 
      return new DataAccess(); 
    } 
    }; 
    private String databasepath; 

    public static DataAccess getInstance() { 
     return THREAD_LOCAL.get(); 
    } 
} 

हो जाएगा ताकि, हालांकि, एक स्मृति रिसाव का कारण है। तो तुम एक अनुरोध के शुरू में एक Servlet Filter का उपयोग मान सेट करने के लिए और फिर अंत में इसे हटाने के लिए की जरूरत है, कुछ की तरह:

public void doFilter(ServletRequest request, 
     ServletResponse response, FilterChain chain) 
     throws IOException, ServletException { 
     DataAccess.set(new DataAccess("SomeValue")); 
     try { 
     chain.doFilter(request, wrapper); 
     } finally { 
     DataAcess.remove(); 
     } 
    } 

बार जब आप एक classFilter आप इस प्रकार आपके web.xml में जोड़ने के लागू करता है :

<!--Filter for adding in dataccess objects--> 
<filter> 
    <filter-name>DataccessFilter</filter-name> 
    <filter-class>my.package.DataccessFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>DataccessFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

This पेज एक फिल्टर और उसके मैपिंग का एक उदाहरण देता है।
और अपने DataAccess देखने की तरह होगा:

public class DataAccess{ 
    private static ThreadLocal<DataAccess> THREAD_LOCAL = new ThreadLocal(); 
    private String databasepath; 

    public DataAcess(final String databasepath) { 
     this.databasepath = databasepath; 
    } 

    public static DataAccess getInstance() { 
     return THREAD_LOCAL.get(); 
    } 
    public static void set(final DataAccess dataAccess) { 
     THREAD_LOCAL.set(dataAccess); 
    } 
    public static void remove() { 
     THREAD_LOCAL.remove(); 
    } 
} 

बनें ThreadLocal साथ अत्यंत सावधान के रूप में यह शायद जावा में मेमोरी लीक की संख्या एक कारण है। वेब सर्वर है कि धागा पूल के साथ आप और भी अधिक गंभीर बग मिल अगर तुम उन्हें ठीक से साफ नहीं है सकते हैं।

+0

+1, मैं बस इसे लिखना चाहता था, लेकिन आप तेज़ थे :) – gaborsch

+1

एसओ पर उत्तरों की गति ने मुझे हमेशा आश्चर्यचकित कर दिया है ... –

+2

ध्यान दें कि 'थ्रेडलोकल काम नहीं करता अगर आप कुछ खास इस्तेमाल करते हैं, उदाहरण के लिए एसिंक्रोनस ईजेबी, धूमकेतु/निरंतरता, क्योंकि वे चल रहे थ्रेड को दूसरे के साथ बदल देंगे। – gaborsch

0

लग रहा है कि ThreadLocal अपने यूज-केस में आपकी मदद चाहिए:

http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html

इस वर्ग के धागे की स्थानीय चर प्रदान करता है। इन चरों कि प्रत्येक धागा है कि (अपने get या विधि सेट के माध्यम से) एक तक पहुँचता है अपने आप ही है में अपने सामान्य समकक्षों से भिन्न होते हैं, स्वतंत्र रूप से चर के प्रतिलिपि प्रारंभ।