Es gibt eine einfache dumme Frage, die mich stört und in meinem Kopf mehrere Argumente vorbringt. Ich möchte alle Zweifel an den folgenden Fragen ausräumen.
class Clstest{
public static String testStaticMethod(String inFileStr) {
// section 0
// section 1
// do something with inFileStr
// section 2
// section 3
return inFileStr;
}
}
Nehmen wir an, es gibt fünf Threads, die jeweils gleichzeitig einen Aufruf ausführen Clstest.testStaticMethod("arg-n")
.
Thread 1 ruft auf Clstest.testStaticMethod("arg-1")
.
Wenn sich Thread 1 in Abschnitt 1 befindet, ruft Thread 2 auf Clstest.testStaticMethod("arg-2")
.
Was passiert dann mit Thread 1? Wird es in den Schlafzustand gehen?
Wenn Thread 1 die Chance hat, wird die Ausführung von Abschnitt 1 fortgesetzt, in dem sie angehalten wurde?
Wie passiert es, wenn alle fünf Threads ein Clstest.testStaticMethod
und dasselbe Clstest.testStaticMethod
gemeinsam nutzen?
Gibt es eine Möglichkeit, die inFileStr
von mehreren Threads gesendeten auszutauschen?
quelle
Antworten:
Die Antwort von Hans Passant ist gut. Aber ich dachte, ich würde versuchen, es jedem, der darauf stößt und neu in Java ist, auf einer etwas einfacheren Ebene zu erklären. Hier geht..
Der Speicher in Java ist in zwei Arten unterteilt - den Heap und die Stacks. Auf dem Haufen leben alle Objekte und auf den Stapeln erledigen die Threads ihre Arbeit. Jeder Thread hat seinen eigenen Stapel und kann nicht auf die Stapel des anderen zugreifen. Jeder Thread hat auch einen Zeiger auf den Code, der auf das Codebit zeigt, das gerade ausgeführt wird.
Wenn ein Thread eine neue Methode ausführt, speichert er die Argumente und lokalen Variablen in dieser Methode auf einem eigenen Stapel. Einige dieser Werte können Zeiger auf Objekte auf dem Heap sein. Wenn zwei Threads dieselbe Methode gleichzeitig ausführen, zeigen beide ihre Codezeiger auf diese Methode und haben ihre eigenen Kopien von Argumenten und lokalen Variablen auf ihren Stapeln. Sie stören sich nur, wenn die Dinge auf ihren Stapeln auf dieselben Objekte auf dem Haufen zeigen. In diesem Fall können alle möglichen Dinge passieren. Aber wie Hans betont, sind Strings unveränderlich (können nicht geändert werden), sodass wir sicher sind, wenn dies das einzige Objekt ist, das "geteilt" wird.
So viele Threads können dieselbe Methode ausführen. Sie werden möglicherweise nicht gleichzeitig ausgeführt. Dies hängt davon ab, wie viele Kerne sich auf Ihrem Computer befinden, da die JVM Java-Threads Betriebssystem-Threads zuordnet, die auf Hardware-Threads geplant sind. Sie haben daher wenig Kontrolle darüber, wie diese Threads verschachtelt sind, ohne komplexe Synchronisationsmechanismen zu verwenden.
Beachten Sie, dass das Schlafen etwas ist, was ein Thread sich selbst antut.
quelle
Nein, das Ausführen eines Threads wirkt sich nicht auf andere Threads aus, solange diese nicht absichtlich miteinander synchronisiert werden. Wenn Sie mehr als einen Prozessorkern haben, wie dies bei allen neueren Computern der Fall ist, werden diese Threads wahrscheinlich genau zur gleichen Zeit ausgeführt. Dies ist etwas weniger wahrscheinlich, wenn Sie 5 Threads starten, da Ihr Computer möglicherweise nicht über genügend Kerne verfügt. Das Betriebssystem ist gezwungen, zwischen ihnen zu wählen, sodass sie jeweils etwas Zeit zum Ausführen haben. Der Job des Thread-Schedulers. Ein Thread befindet sich dann nicht im Ruhezustand. Er wird einfach angehalten und wartet darauf, dass der Thread-Scheduler ihm die Möglichkeit gibt, ausgeführt zu werden. Es wird dort fortgesetzt, wo es vom Scheduler unterbrochen wurde.
Es gibt keine solche Möglichkeit, Threads haben einen eigenen Stapel, sodass jedes Methodenargument und jede lokale Variable für jeden Thread eindeutig ist. Die Verwendung eines Strings garantiert außerdem, dass diese Threads sich nicht gegenseitig stören können, da Strings unveränderlich sind.
Es gibt keine solche Garantie, wenn das Argument auf eine andere Art von veränderlichem Objekt verweist. Oder wenn die Methode selbst statische Variablen verwendet oder auf Objekte auf dem Heap verweist. Die Synchronisierung ist erforderlich, wenn ein Thread das Objekt ändert und ein anderer Thread es liest. Das Schlüsselwort lock in der Sprache C # ist die Möglichkeit, die erforderliche Synchronisierung zu implementieren. Die Tatsache, dass die Methode statisch ist, bedeutet nicht, dass eine solche Synchronisation niemals erforderlich ist. Wahrscheinlich nur weniger , da Sie müssen nicht über Gewinde sorgen das gleiche Objekt zugreifen (gemeinsame Nutzung dieses ).
quelle