2013-02-19 33 views
7

GlassFish üzerinde RESTful java arka ucunu çalıştırıyorum. Buna ek olarak bir webapp projesine koyabildiğim bir HTML5/JS öneki (ve sonra arka uçbirimi bağımlı olarak dahil et) veya farklı bir konumdaki bir IIS web sunucusunda çalıştırabiliyorum. CORS bir sorun değil. Bu şu sorunu çözer ne olursa olsun:ThreadLocal Singleton

Durum:

  1. Kullanıcı1 oturum açtığında ve veritabanı yolu veritabanına 'db/kullanici1 /'
  2. Kullanıcı1 uçların Değer 1 "olarak ayarlanır
  3. Kullanıcı2 günlükleri ve veritabanı yolu olarak ayarlanır 'db/kullanici2 /'
  4. Kullanıcı1

Kullanıcı1 olmazdı veritabanından 'Değerini 1' silmeye çalışır

  • Veritabanını db/user2 olarak değiştirildiği ve bu veritabanında Değer 1 olmadığı için, Değer 1'i db/user1'den silebilir. Bir tekil olarak görür, ama sadece o kullanıcının İçten dişli böylece

    public class DataAccess{ 
        private static DataAccess dataaccess; 
        private String databasepath; 
    
        public static DataAccess getInstance() { 
         if (dataaccess == null) { 
          dataaccess = new DataAccess(); 
         } 
        } 
    } 
    

    nasıl getInstance() yöntemini değiştirebilir? Threadlocal diye bir şey gördüm ama tam olarak anlamadım, belki de bir çözüm mü?

    Herhangi bir yardım, kesinlikle takdir edilmektedir.

  • +0

    9 soru sordunuz ve kabul ettiniz 0 Lütfen bunu geliştirin. – gaborsch

    +0

    Bir yanıtı nasıl kabul ederim –

    +0

    SSS bölümündeki bu bölümü okuyun, hatta ekran görüntüleri vardır: http://stackoverflow.com/faq#howtoask – gaborsch

    cevap

    9

    Sen bir fabrika deseni ThreadLocal sınıfını kullanabilirsiniz:

    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(); 
        } 
    } 
    

    Bu irade, ancak, bir bellek sızıntısına neden. Yani bir istek başında değerini ayarlamak için bir Servlet Filter kullanmak ve sonunda da silmek gerekir bazıları gibi:

    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(); 
         } 
        } 
    

    Eğer böylece web.xml eklemek Filter uygulayan bir class sahip olduktan sonra :

    <!--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 sayfa bir filtre ve eşleştirmeleri bir örnek verir. muhtemelen Java bellek sızıntıları numaralı nedenidir olarak

    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 ile son derece Dikkatli olun: gibi
    Ve DataAccess görünürdü. İş parçacığı havuzlarına sahip web sunucuları sayesinde, bunları düzgün bir şekilde temizlemezseniz daha da ciddi hatalar alabilirsiniz.

    +0

    +1, Sadece aynısını yazmak istedim, ama daha hızlısın :) – gaborsch

    +1

    SO cevapları her zaman beni şaşırttı ... –

    +2

    Özel bir şey kullanırsanız, ThreadLocal işlevinin çalışmadığına dikkat edin, örn. Eşzamansız EJB'ler, Kuyruklar/Süreklilikler, çünkü bunlar çalışan İpliği bir diğeriyle değiştireceklerdir. – gaborsch

    0

    ThreadLocal lütfen kullanım durumunda size yardımcı gerektiğini görünüyor:

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

    Bu sınıf parçacığı yerel değişkenleri sağlar. Bu değişkenler, (alma veya ayar yöntemiyle) erişen her bir iş parçacığının, bağımsız olarak başlatılan değişkeninin kendi kopyası olan , normal muadillerinden farklıdır.