2016-04-20 15 views
4

Ich habe eine Klasse, die eine static synchronized-Methode verwendet, um HTTP-Aufrufe durchzuführen.Ist es sicher, eine statische synchronisierte Methode aus nicht verwandten Klassen aufzurufen?

Ich habe auch eine ExecutorService.

Es gibt mehrere Runnable-Klassen, die diese Methode aufrufen. Die Methode akzeptiert URLs, POST/GET-Informationen und Argumente und gibt entweder einen Fehlercode zurück, wenn die Antwort nicht 200 ist, oder eine XML-Zeichenfolge, die von der Runnable-Klasse weiterverarbeitet wird.

Wenn mehrere Threads diese Methode nach dem Platzieren in ExecutorService aufrufen, wird das in Ordnung sein? Wird es scheitern?

Was ist die ideale Möglichkeit, mehrere HTTP-Aufrufe über ExecutorService zu verarbeiten?

+1

Ja, es ist sicher, da das Monitorobjekt vom Objekt auf Klassenebene gehalten wird. – 11thdimension

+1

Wenn Ihre statische Methode zustandslos ist, muss sie möglicherweise nicht synchronisiert werden. – Andreas

+2

Warum wird die Methode synchronisiert? Verwendet es einen Zustand auf Klassenebene? –

Antwort

1

Ja, es ist der wichtigste Punkt mit dem synchronize Label in Java :)

Es ist wie ein Mutex zu Beginn der Funktion et Sperren diesen gleichen Mutex bei der Rückkehr am Ende zu entriegeln.

In diesem Fall ist der Mutex Object-weise, also wird das Aufrufen einer synchronisierten Methode die anderen sperren. Seien Sie sich bewusst,

+0

Synchronisierte Blöcke sind mit einem Monitor verriegelt, der Monitor muss den gleichen Block haben, damit sich zwei Anrufe gegenseitig ausschließen. Nicht jede synchronisierte Methode ist für jeden Thread exklusiv. Wenn Monitore unterschiedlich sind, können synchronisierte Methoden parallel aufgerufen werden. – 11thdimension

+0

In diesem Fall ist der Monitor die Klasse, da es sich um eine synchronisierte Methode handelt und nicht um einen synchronisierten Block. Wenn er also die Methode aufruft, ist der Monitor des Objekts gesperrt. – KerbKerb

+1

Ja genau, das ist nicht klar in Ihrer Antwort. – 11thdimension

2

Jede Frage über "Thread-Sicherheit" muss eine Frage über veränderbar sein, gemeinsame Daten. Sofern Ihre Threads keine änderbaren Daten teilen, gibt es kein Threadsicherheitsproblem.

Ein veränderbares Objekt oder eine Gruppe veränderbarer Objekte in Ihrem Programm ist "Thread safe", wenn es für die Aktion eines einzelnen Threads nicht möglich ist, das Objekt/die Gruppe in einen "schlechten" Zustand zu versetzen andere Themen.

die einfachste, gebräuchlichste Weg, Thread-Sicherheit eines Objekts/Gruppe zu gewährleisten ist mutual exclusion zu verwenden (das heißt, synchronized Blöcke und/oder Methoden). Wenn jede Methode, die oder READS die Daten ändert, tut dies nur innerhalb von Code-Blöcken, die alle synchronized auf dem gleichen Objekt sind, und wenn die Mutator-Funktionen immer sicherstellen, dass das Objekt/Gruppe in einem gültigen Zustand ist, bevor synchronized Block verlassen, dann ist dieses Objekt/diese Gruppe "threadsicher".


Ihre Frage erwähnt keine Daten. Ihre Frage erwähnt nicht, ob es mögliche "ungültige" Zustände gibt, in denen die Daten enthalten sein könnten. Ihre Frage bezieht sich auf eine Methode, aber nicht auf andere Methoden, die auf dieselben Daten zugreifen.

Wenn die fragliche Methode static und synchronized ist, dann garantiert das, dass keine zwei Threads jemals die Methode gleichzeitig eingeben können, aber das macht die Daten nicht "threadsicher", wenn es solche gibt alle andere Methoden, die auf dieselben Daten zugreifen oder sie ändern.

Alle Codeblöcke und/oder Methoden, die auf die Daten zugreifen, müssen synchronized sein, und sie müssen alle auf demselben Sperrobjekt synchronisiert sein.


Eigentlich Synchronisieren jeder Zugriff könnte zu viel des Guten.Aber es gibt keine Möglichkeit, das zu wissen, ohne zu wissen, welche Daten die Threads teilen und was sie mit den Daten machen.

Es geht nur um die Daten.

+0

Ich werde meine Frage bearbeiten, um klarer zu sein. Danke für die Antwort, es war sehr hilfreich. –

0

Mit ExecutorService Tasks Aufruf eine statische synchronisierte Methode wird ein Engpass sein. Nur ein Thread kann diese Methode gleichzeitig ausführen.

Wenn alle Aufgaben in der ExecutorService diesen Aufruf ausführen müssen, dann im Wesentlichen Sie möglicherweise den Zweck der mehrere Threads zu besiegen, wie die meisten Threads verbringen ihre Zeit warten auf den Monitor auf der Klasse zu erwerben, so können sie rufe die statische Methode auf.

Die statische synchronisierte Methode dient dazu, den gemeinsamen Status vor unsicherem gleichzeitigen Zugriff zu schützen. Versuchen Sie, jeder Aufgabe ihren eigenen Status zu geben und den Austausch so weit wie möglich zu eliminieren.

+0

Ich sehe, also, wenn ich das richtig verstehe, wenn ich die synchronisierte Methode entferne, würde der Flaschenhals verschwinden. –

+0

@ James.Wyst: das synchronisierte Schlüsselwort ist wahrscheinlich aus gutem Grund da, du willst den Engpass nicht entfernen, nur um Datenrennen oder andere Threadsicherheitsprobleme zu verursachen. Geben Sie jeder Task einen eigenen httpclient, um ihre Aufrufe auszuführen, und geben Sie ihr eigene Daten zum Bearbeiten an. –