2015-09-22 19 views
5

ProcessOutbox adlı bir yöntem var. İş parçacığı güvenli olmasını istiyorum. Bir iş parçacığı çalışırken başka bir iş parçacığı bu yöntemi çağırmak istemiyorum. Bunu şu şekilde uygulamıştım. Doğru yaptım mı? Uygulamamda herhangi bir boşluk var mı? Varsa, lütfen nasıl çözebileceğime dair öneride bulunun.Aşağıdaki bağlamda iplik güvenliğini nasıl sağlayabilirim?

this.start(); 
    outboxLock.lock(); 
    timer = new Timer(); 
    try{ 
    timer.scheduleAtFixedRate(new TimerTask() { 
      public void run() { 
       processOutbox(); 
      } 
     }, 0, period); 
    } finally{ 
     outboxLock.unlock(); 
    } 
+4

Zamanlamayı yalnızca kilitlediniz. İcra hala threadafe değildir. – Fildor

+0

Nasıl yaparım? Lütfen tavsiye. – mayooran

+0

Sınıf düzeyinde statik değişken üzerinde senkronize etmenizi öneririm. –

cevap

5

Eğer yöntem processOutbox olmak için, anahtar kelimeyi synchronized kullanmalısınız:

public class YourClass{ 
    public synchronized void processOutbox(){ 
     //do all you want 
    } 
} 

diğer bilgiler de:

YourClass örneğidir https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html denilen kodunuzda Eğer varsa örneğin myInstance için, processOutbox() numaralı tüm çağrılar iş parçacığı için güvenli olacak, çünkü bunlar örnek düzeyinde kilitlenecektir. Örneğin

: thread1 çağrıyı için "processOutbox"

Ama bitene kadar bekliyor olacak thead2

İşte
YourClass myInstance = new YourClass(); 
Thread thread1 = new Thread(){ 
    public void run(){ 
     myInstance.processOutbox(); 
    } 
    } 
Thread thread2 = new Thread(){ 
    public void run(){ 
     myInstance.processOutbox(); 
    } 
    } 
thread1.start(); 
thread2.start(); 

örneğin:

YourClass myInstance = new YourClass(); 
YourClass myInstance2= new YourClass(); 
Thread thread1 = new Thread(){ 
    @Override 
    public void run(){ 
     myInstance.processOutbox(); 
    } 
}; 
Thread thread2 = new Thread(){ 
    @Override 
    public void run(){ 
     myInstance2.processOutbox(); 
    } 
} 
thread1.start(); 
thread2.start(); 

thead2 olacak DEĞİL beklemeye çünkü farklı örneklerde yöntemi çağırıyorlar.

Özellikle ReentrantLock kullanımı hakkında sorular sordu - Bu yanıtı buna ekliyorum, çünkü bu doğru. Ayrıca bunun yerine tryLock kullanarak engellemek için onları neden olmadan kilit dışı diğer konuları tutmak şey yapabilirsiniz çünkü

public class YourClass { 
    private Lock outboxLock = new ReentrantLock(); 
    public void processOutbox() { 
     outboxLock.lock() 
     try { 
      // do stuff 
     } finally { 
      outboxLock.unlock() 
     } 
    } 
} 

Ben özellikle bu söz.

public class YourClass { 
    private Lock outboxLock = new ReentrantLock(); 
    public void processOutbox() { 
     if(outboxLock.tryLock()) { 
      try { 
       // do stuff 
      } finally { 
       outboxLock.unlock() 
      } 
     } 
    } 
} 
+0

** Tek bir iş parçacığı çalışırken başka bir iş parçacığı bu yöntemi çağırmak istemiyorum. ** –

+0

Java API: "Bir iş parçacığı, bir nesne için eşitlenen bir yöntemi yürütürken, aynı için eşitlenen yöntemleri çağırmak üzere tüm diğer iş parçacıkları nesne ile ilk iş parçacığı bitene kadar nesne bloğu (yürütmeyi askıya al). –

+0

Reentrantlock kullanarak aynı şeyi nasıl yapabilirim? lütfen tavsiye goku :) – mayooran