2015-11-23 11 views
8

İşte kod:Bu koddaki sayacı değiştirmek için Collection.size() öğesini kullanabilir miyim?

public class LogService { 
    private final BlockingQueue<String> queue; 
    private final LoggerThread loggerThread; 
    private final PrintWriter writer; 
    @GuardedBy("this") private boolean isShutdown; 
    @GuardedBy("this") private int reservations; // <-- counter 
    public void start() { loggerThread.start(); } 
    public void stop() { 
     synchronized (this) { isShutdown = true; } 
     loggerThread.interrupt(); 
    } 
    public void log(String msg) throws InterruptedException { 
     synchronized (this) { 
      if (isShutdown) 
       throw new IllegalStateException(...); 
      ++reservations; 
     } 
     queue.put(msg); 
    } 
    private class LoggerThread extends Thread { 
     public void run() { 
      try { 
       while (true) { 
        try { 
         synchronized (LogService.this) { 
          if (isShutdown && reservations == 0) 
           break; 
         } 
         String msg = queue.take(); 
         synchronized (LogService.this) { 
          --reservations; 
         } 
         writer.println(msg); 
        } catch (InterruptedException e) { /* retry */ } 
       } 
      } finally { 
       writer.close(); 
      } 
     } 
    } 
} 

Bu Uygulama kitabın Java eşzamanlılık bir pasajı, ve ben biz sadece sayısını almak için queue.size() kullanmaya devam edebileceği için belki sayaç reservations gereksiz olduğunu düşünüyorum queue öğesinde.

Doğru muyum?

+1

Sırasıyla "koy" ve "al" senkronize edilmez. 'rezervasyonları' değişikliği. –

cevap

5

Hayır, aslında bu bir kilitlenme yaratır. size Paralel olarak kullanmak istiyorsanız, put ve take'u eşitlemeniz gerekir.Ancak take engelleniyor ve artık put numaralı çağrıyla aynı nesne üzerinde senkronize edilmiş bir take çağrı engelleme yapacaksınız. take, bir şey put olana kadar dayanamaz. put, take numaralı kilidi açana kadar koyamaz. Bu bir kilitlenme. "Çekinceleri" kullanma

+0

"put" ve "take" yönteminin kaynak kodunu inceledim ve "Lock" ile senkronize edilmiş gibi görünüyor. – user2916610

+0

@ user2916610, 'size' de eşitlendiyse sorun olurdu. – djechlin

+0

'size' de senkronize edilir. – user2916610

0

değişken iyi alan tasarımı çok daha anlamlı boyutundan daha o çünkü, sen performans tarafında mevcut rezervasyon vb

toplam sayısı gibi alan kavramını ifade için kullanabilirsiniz

ArrayBlockingQueue - çağrı boyutu işlevi yavaşlığıyla sonuçlanacaktır, çünkü boyutu okumak için kilidi alır ve aynı zamanda işlemi yavaşlatır veya yavaşlatır.

LinkedBlockingQueue - Arama boyutu atomik/volatil okunur ve performansa sahiptir.

İlgili konular