2016-05-31 7 views
0

Ich habe eine MyService Klasse, die doTask() nur eine public Methode hat, verwende ich synchronized Schlüsselwort zu halten, in eine Thread-sichere Weise zugegriffen wird:sollte ich 'synchrnonized' Schlüsselwort auch auf meiner privaten Funktion verwenden?

public class MyService { 

String myTaskId; 
public MyService { 
    myTaskId = getTaskId(); 
} 

public synchronized void doTask() { 
    myTaskId = getTaskId(); 
    ... 
} 

private String getTaskId() { 
    ... 
} 
} 

Es gibt eine private Funktion getTaskId() die sowohl in aufgerufen wird, Konstruktor und in doTask() Funktion. Ich frage mich, ist es wert, Keyword auch auf getTaskId() Funktion synchronisiert zu haben?

+0

Ja; nur für den Fall, dass Sie eine weitere nicht synchronisierte Methode hinzufügen, die in Zukunft auch 'getTaskId()' aufruft. Beachten Sie, dass Sie auch die Zuweisung im Konstruktor synchronisieren sollten, um die Sichtbarkeit des zugewiesenen Werts zu gewährleisten. –

+0

@AndyTurner, aber ist es notwendig, im Konstruktor einen synchronisierten Block zu haben? Ich meine nur, nachdem MyService vollständig aufgebaut ist, kann die 'doTask()' als richtig bezeichnet werden? Könnten Sie bitte erläutern, in welchem ​​Szenario das Hinzufügen eines synchronisierten Blocks im Konstruktor erforderlich ist? Oder denken Sie, dass 'MyService' in einem Thread erstellt wird, während auf die gleiche Instanz im anderen Thread zugegriffen wird? Ich bin jetzt verwirrt in diesem Thema. –

+2

Da 'myTaskId' nicht endgültig ist, kann die JVM die Rückgabe des Konstruktors und die Zuweisung von' myTaskId' neu anordnen, was bedeutet, dass einige Threads den Wert vor der Zuweisung lesen können. Sie benötigen den 'synchronisierten' Block, um zu erzwingen, dass die Zuweisung vor der Rückgabe des Konstruktors erfolgt. –

Antwort

-1

Diese Frage steht im Zusammenhang mit einer anderen Frage zum Stapelüberlauf. If a synchronized method calls another non-synchronized method, is there a lock on the non-synchronized method

Da getTaskId nicht synchronisiert ist, wird keine Sperre erstellt, wenn eine synchronisierte Methode sie aufruft. Aber auch hier schafft die private Sperre keinen Effekt.

Um Ihre Frage zu beantworten, solange sie privat bleibt und alle Methoden, die diese Methode aufrufen, synchronisiert sind, müssen Sie dies nicht explizit andeuten.

+0

Aber wie Sie sehen, ruft mein Konstruktor sie auch an, also ist Ihre Antwort immer noch nicht so klar wie erwartet. –

+0

Das ist subjektive Frage. Ich würde die GetTaskId synchronisieren, wenn es die Möglichkeit gibt, ein veraltetes Objekt zu lesen. Wenn taskId ein statischer Wert ist, der sich nicht viel ändert, würde ich kein synchronisiertes Schlüsselwort hinzufügen. –

-1

, wenn das Objekt erstellen, wird der Konstruktor first.After dass aufgerufen werden, Verfahren doTaskk() kann sein invoked.So es nicht notwendig ist, synchronisieren hinzufügen auf getTaskId

0

Ihr Beispielcode zeigt nicht irgendwelche Variablen. Die Leute reden über Synchronisierungsmethoden, aber der Zweck der Synchronisation hat nichts mit Methoden zu tun: Es geht darum, geteilte Daten zu schützen.

Wo ich arbeite, ist es sehr üblich, synchronized private Methoden und/oder synchronized Blöcke innerhalb private Methoden zu sehen. Wir tun es immer dann, wenn zwei oder mehr Threads gleichzeitig in die Methode/den Block eintreten können, um dieselben Daten zu bearbeiten.

Das Wissen, dass eine Methode private ist, sagt nichts darüber aus, was Threads sie nennen könnten. Es sagt Ihnen nur, dass die sofortige Aufrufer irgendwo in der gleichen Klasse sein wird.

Verwandte Themen