2012-06-04 16 views
10

Diğer iş parçacıkları tarafından artık başvurulmadığında, kapatılabilir nesneyi düzgün şekilde kapatmak istiyorum.ReferenceQueue ve WeakReference'ı Kullanma

Bazı küçük sınamalar yazdım, ancak nesne aktarıldıktan sonra get yönteminin null değerine dönüşmesi, yani yoklama yöntemi, başvurusu olmayan uygun Object'i döndürür.

public static void main(String[] args) 
    { 
    ReferenceQueue<Closeable> reaped = new ReferenceQueue<Closeable>(); 
    Closeable s = <SOME CLOSEABLE IMPL>; 
    WeakReference<Closeable> ws = new WeakReference<Closeable>(s, reaped); 
    s = null; 

    System.gc(); 
    Closeable ro = (Closeable)reaped.poll().get(); 
    ro.close(); 
    } 

Şimdiden teşekkürler. Herhangi bir yardım takdir edilecektir.

cevap

7

İlk önce, yalnızca kapanıyorsa, PhantomReference kullanın. Ardından, başvuru sırasından, poll(), başvuruyu geri alacağınızı garanti etmez. ve gerçek nesneyi (referans) geri alamazsınız.

Closeable s ürününüzün kapalı olduğundan emin olmak istiyorsanız, Map<Reference<?>, Closeable> numaralı telefondan bize ulaşabilirsiniz. Daha sonra, poll() referans sıranız olduğunda, en sonunda ref'u alacaksınız, daha sonra Closeable haritasından almak için kullanmak zorundasınız.

class MyThing { 
     Closeable c; 
    } 

    Map<Reference<MyThing>, Closeable> m = new HashMap(); 
    ReferenceQueue<MyThing> reaped = new ReferenceQueue<MyThing>(); 

    MyThing mt = new MyThing(); 
    mt.c = new MyClosable(); 

    Reference<MyThing> pref = new PhantomReference<MyThing>(mt, reaped); 
    m.put(pref, mt.c); 

    mt = null; 


    System.gc(); 
    Reference<MyThing> rf = reaped.poll(); 
    while (rf != null) { 
    m.get(rf).close(); 
    rf = reaped.poll(); 
    } 

Not bunu yapmak ya da gerçekten ne yaptığını anlamak yoksa, bu tür şeyleri yapmak YAPMAYIN gerçek bir sebep yoksa.

Sen finally dosyalarınızı kapatabilir ve vb dosyaları, priz, ilgili BTW, onlar (onlar zaten böyle hızlı tepki için finalize()

+0

Merhaba sayesinde uygulamak sizin için kapalıdır, bu Lucene IndexSearcher hakkındaki bu. – yan

+0

Sadece denedim, System.gc() 'den sonra ReferenceQueue boyutu sıfırdır – yan

+0

@yan, nesnelerin JVM'den çıkarken bile System.gc() 'den sonra GC'leri alacağının bir garantisi yoktur. iş mantığınız için kesinleştirme kullanmayın.Yalnızca önbellekleme ve (sonuçta) kaynak sızıntılarını önleme gibi özel amaçlar için vardır.İmzalama –