2016-10-23 2 views
3

Ich habe ein Szenario, hat ziemlich viel gesucht, aber keine befriedigende Antwort bekommen.Java-Methoden thread sicher

Es gibt eine Service-Klasse ist, WebserviceInvokerService,

class WebserviceInvokerService { 
    @Override 
    public void synchronized callBackFun() {...} 
} 

callBackFun ==> ist die Funktion, die aufgerufen wird, wenn ein Ereignis (ein Ereignis) auftritt.

In callBackFun Ich DB überprüfen und entsprechend einen Service-Aufruf (keine Instanz Mitglieder der Klasse sind in diesem Geschäft beteiligt).

Ich habe CallBackFun synchronisiert. Es besteht die Möglichkeit, dass mehrere Instanzen von WebserviceInvokerService erstellt werden und CallBackFun für diese Objekte aufgerufen wird.

Ich möchte CallBackFun "synchron" über die Objekte aufgerufen werden. Also wird das "Synchronisieren" für CallBackFun in einem solchen Szenario Sinn machen.

+0

Sie müssen synchronisieren, wenn der veränderbare Status eines Objekts von zwei oder mehr Threads geteilt wird. Da Sie uns nicht gezeigt oder uns von dem Zustand erzählt haben, den Sie schützen möchten, ist es nicht möglich, Ihre Frage zu beantworten. – scottb

+0

Wenn Sie über Objekte hinweg synchronisieren möchten, sollten Sie synchronisierte (WebserviceInvokerService.class) {...} in der CallBackFun-Methode verwenden – Paulo

+0

Es klingt ein bisschen wie Sie hinzufügen "synchronisiert" ohne wirklich zu verstehen, warum. Was ist der änderbare Zustand, in dem sich die Methode ändert, sodass sie Thread-unsicher wird? – Kayaman

Antwort

2

Wenn Sie mehrere Instanzen java WebserviceInvokerServices die Methoden werden in jedem dieser Fälle synchronisiert werden, aber nicht über die Instanzen.

Was Sie vielleicht suchen, ist ein Lock.

Sie können dies versuchen:

private final static Lock lock = new ReentrantLock(); 

@Override 
public void callBackFun() { 
    lock.lock(); 
    try { 
     // Do things here 
    } finally { 
     lock.unlock(); 
    } 
} 

EDIT: Added das letzte Schlüsselwort wie @Wyzard erwähnt

+4

erwähnt Und das Schloss sollte fast sicher "endgültig" erklärt werden, weil Sie es nie während des Programms mit einer anderen Sperre ersetzen wollen. – Wyzard

2

Um zwischen Instanzen zu synchronisieren, sollten Sie die Synchronisation mit der statischen Referenz verwenden.

class WebserviceInvokerService { 
    @Override 
    public void callBackFun() { 
     synchronized(WebserviceInvokerService.class) {... } 
    } 
} 
+1

Anstatt auf das Klassenobjekt selbst zu synchronisieren, ist es besser, eine 'private statische final'-Variable zu verwenden. Auf das Klassenobjekt kann in der gesamten Anwendung zugegriffen werden, und andere Teile der Anwendung können es für andere, nicht verwandte Zwecke synchronisieren, die nicht mit der eigenen internen Selbstsynchronisation der Klasse interagieren sollten. – Wyzard

+0

wie in der Antwort von @ Lμk4s –

-1

Da callBackFun keine Instanz Mitglieder verwenden (per Post: keine Instanz Mitglieder der Klasse sind in diesem Geschäft beteiligt)

können Sie diesen Code in static synchronized Methode so setzen, dass Classlevel Sperre vorhanden sein wird. Rufen Sie es von Ihrer Instanzmethode

public synchronized void callBackFun() { 
    actualFunLogic(); 
} 

private static synchronized void actualFunLogic() 
{ 
    ..... 
}