Cum pentru a sincroniza o variabilă statică printre firele de funcționare diferite instanțe ale unei clase în Java?

Știu că utilizarea de "sincronizare" cuvinte cheie înainte de a o metodă aduce sincronizare la acel obiect. Asta este, 2 fire care rulează aceeași instanță a obiectului vor fi sincronizate.

Cu toate acestea, deoarece sincronizarea este la nivel de obiect, 2 fire care rulează diferite instanțe de obiect nu vor fi sincronizate. Dacă avem o variabilă statică într-o clasă Java care este numit prin metoda, ne-ar dori să fie sincronizate între instanțe de clasă. Cele două cazuri se execută în 2 fire diferite.

Putem realiza sincronizarea în felul următor?

public class Test  
{  
   private static int count = 0;  
   private static final Object lock= new Object();    
   public synchronized void foo() 
  {  
      synchronized(lock)
     {  
         count++;  
     }  
  }  
}

Este adevărat că de când ne-am definit un obiect "blocare", care este static și suntem folosind cuvântul cheie sincron pentru că de blocare, variabilă statică "count" este acum sincronizat peste cazuri de clasa "Test"?

Comentarii la întrebare (2)
Soluția

Există mai multe moduri de a sincroniza accesul la o variabilă statică.

  1. Utilizați un sincronizate metodă statică. Aceasta sincronizează pe obiect de clasă.

public class Test { private static int count = 0;

public static sincronizate void incrementCount() { count++; } }

  1. În mod explicit sincroniza pe obiect de clasă.

public class Test { private static int count = 0;

public void incrementCount() { sincronizate (Test.class) { count++; } } }

  1. Sincronizarea de pe un alt obiect static.

public class Test { private static int count = 0; private static final Obiect countLock = new Object();

public void incrementCount() { sincronizate (countLock) { count++; } } }

Metoda 3 este cel mai bun în multe cazuri, deoarece obiectul de blocare nu este expus în afara clasei.

Comentarii (5)

Daca're pur și simplu de partajare un contor, luați în considerare utilizarea o AtomicInteger sau o altă potrivit clasă din java.util.concomitent.atomic pachet:

public class Test {

    private final static AtomicInteger count = new AtomicInteger(0); 

    public void foo() {  
        count.incrementAndGet();
    }  
}
Comentarii (1)

Da, este adevărat.

Dacă veți crea două instanță a clasei

Test t1 = new Test();
Test t2 = new Test();

Atunci t1.foo și t2.foo ambele sincroniza pe același obiect static și, prin urmare bloca reciproc.

Comentarii (1)

Puteți sincroniza codul de clasă. Ar fi mai simplu.

   public class Test  
    {  
       private static int count = 0;  
       private static final Object lock= new Object();    
       public synchronized void foo() 
      {  
          synchronized(Test.class)
         {  
             count++;  
         }  
      }  
    }

Sper că veți găsi acest răspuns util.

Comentarii (2)