2011-01-16 18 views
0

In einer Java-Klasse habe ich eine statische Liste, so dass diese Liste für alle Objekte dieser Klasse freigegeben ist. Die Geschäftslogik in dieser Klasse wird in regelmäßigen Abständen ausgeführt, die von einer Methode ohne Übergabe von Instanzparametern aufgerufen wird um diese run-Methode basierend auf der Liste aufzurufen (Ich werde einige vales in diese Liste basierend auf JMS hinzufügen), diese Liste kann manchmal leer sein und nachdem ich den Lauf beendet habe, lege ich diese Liste leer. Nun ist meine Frage, ob ich synchronisieren muss diese Liste oder nicht?Java statische Liste synchronisieren?

Lassen Sie mich auch wissen, gibt es eine andere Möglichkeit, Wert in einer Objektinstanz (Thread1) an andere Objektinstanz (Thread2) übergeben, außer statische Variable (statische Liste)?

Thx

+0

Ich sehe nicht, warum Sie hier eine statische Liste verwenden. Kannst du etwas Code posten? – lweller

+0

Random comment: Es gibt keinen praktischen Unterschied zwischen der Synchronisation zwischen einer statischen Variablen und einer nicht statischen Variablen (in beiden Fällen ist es das tatsächliche Objekt, das synchronisiert wird/Bedürfnisse passiert) vor Beziehungen, jedoch sind die Klassenvariablen statisch/nicht Ich gehe davon aus, dass das Objekt, auf das die Variable verweist, niemals geändert wird. * Im Allgemeinen * werden viele Aufgaben, die mit statischen Variablen erledigt werden, auf andere Weise besser erledigt. –

+0

@pst: Bitte siehe bearbeiten und lassen Sie mich die anderen Möglichkeiten kennen – JavaUser

Antwort

1

Wenn die Liste wandelbar und von verschiedenen Threads zugegriffen wird (die es, wie es klingt, ist), dann ja, müssen Sie synchronisieren. (Wenn es unveränderlich ist, dann ist eine andere Option, den statischen Verweis darauf final zu machen.) Ich würde vorschlagen, zuerst die Klassen BlockingQueue zu betrachten, die entworfen wurden, um einen Thread (oder tatsächlich mehrere Threads) hinzuzufügen Elemente zu einer "Liste" und dann haben einen anderen Thread sit Elemente abziehen und verarbeiten sie.

+0

Sie möchten immer noch vorsichtig mit der Verwendung einer endgültigen Liste sein, die Sie nur daran hindert, dieser Variablen eine neue Liste zuzuweisen und die vorhandene nicht zu ändern. – helloworld922

+0

Ja, das stimmt - Ihre Liste muss wirklich unveränderlich sein (indem Sie sie mit Collections.unmodiableList() umhüllen) - Entschuldigung, wenn ich nicht klar darüber war. –

+0

Ja, ich werde zur Laufzeit Werte in diese Liste einfügen – JavaUser

1

Wenn es Zugriffsmöglichkeiten und/oder Aktualisierungen von verschiedenen Threads gibt, müssen diese Vorgänge synchronisiert werden.

Oder um es anders auszudrücken, die nur Fällen, in denen Sie bei der Synchronisierung Operationen auf der Liste verzichtet werden kann, wenn:

  • da nur ein Thread ist, die möglicherweise den Zugang/die Liste aktualisieren, oder
  • Die Liste wird erstellt, initialisiert, in einen unveränderlichen Listenwrapper eingepackt und von einem Thread sicher veröffentlicht ... und dann nie aktualisiert.

Auch lassen Sie mich wissen, gibt es eine andere Art und Weise Wert in einer Objektinstanz (Thread1) zu anderen Objektinstanz (Thread2) passieren andere als statische Variable mit (statische Liste)?

Es gibt viele Möglichkeiten. Zum Beispiel:

  • Sie könnten, dass thread2 der runnable arrangieren hat eine öffentliche Setter, dass thread1 runnable ist ein Wert zu übergeben verwenden können, um Thread2. Dies erfordert einige zusätzliche Synchronisation.

  • Sie könnten veranlassen, dass thread1 und thread2 instanziiert werden mit einem gemeinsamen Objekt oder Objekten, die verwendet werden können, um spate hin und her zu leiten. Wenn es sich bei dem Objekt um eine (synchronisierte) Warteschlange oder Pipe für allgemeine Zwecke handelt, müssen die Threads keine explizite Synchronisierung durchführen.

+0

finden Sie unter Bearbeiten – JavaUser

1

Sie entweder benötigen, um alle auf diese Liste lesen zu synchronisieren und schreibt, oder verwenden Sie eine Multi-Thread-fähig Liste (wie CopyOnWriteArrayList oder sogar ein ConcurrentMap, wenn Sie, dass für anspruchsvollere Sachen verwenden).

Andernfalls müssen Sie gute Gleichzeitigkeitskontrolle haben, so dass verschiedene Threads nicht gegenseitig überschreiben, und auch, dass andere Threads sehen, Änderungen vorgenommen werden.

re edit: Der beste Weg, um Daten zwischen Threads zu übergeben, ist für sie eine Datenstruktur zu teilen. Statische Variablen sind ein Weg, aber es ist nicht die einzige Art zu teilen. Sie können über ein gemeinsames Objekt teilen, das in beiden Threads (zum Beispiel im Konstruktor) übergeben wird. Normalerweise wird dies eine Warteschlange genannt, in die ein Thread schreibt und von der die anderen Threads konsumieren. In Java gibt es einige blockiert Warteschlangen dies einfacher zu machen - sehen viele verschiedene Klassen in diesem Paket http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/package-summary.html

+0

finden Sie unter Bearbeiten – JavaUser

+0

Java 5 Dokumentation? Ew. –

+0

es ist nicht viel anders als 6 sowieso – Chii

1

Auch lassen Sie mich wissen, gibt es eine andere Art und Weise Wert in einer Objektinstanz übergeben (Thread1) zu andere Objektinstanz (Thread2) anders als statische Variable (statische Liste)?

Objektinstanz (Thread1) zu anderen Objektinstanz (Thread2) -> Sie benötigen statische Variable, da Objektinstanzen unterschiedlich sind. Wie Sie jedoch wissen, wenn Thread1 und Thread2 für dieselben Objekte arbeiten, werden Instanzenvariablen der Klasse zwischen Threads geteilt. Also keine Notwendigkeit, sie statisch zu machen.

+0

Wie? ... die Variable sollte statisch sein, da Instanz Variablen nicht über Objekte hinweg geteilt werden ... – JavaUser

+0

Ich sagte: Wenn Thread1 und Thread2 auf gleichen Objekten arbeiten, dann Instanz Variablen der Klasse wird zwischen Threads geteilt. Gleiche Objekte, nicht über Objekte hinweg. – Victor

0

Auch lassen Sie mich wissen, gibt es eine andere Art und Weise Wert in einer Objektinstanz (Thread1) zu anderen Objektinstanz (Thread2) passieren andere als statische Variable mit (statische Liste)?

Hier sind zwei verschiedene Methoden, die hier die Verwendung einer statischen Variablen vermeiden. Es kann mehr geben.

Verfahren # 1

class A implements Runnable { 
    final Object x; 
    public A (Object _x) { 
    x = _x; 
    } 
    ... 
} 

// elsewhere .. hopefully from a NON-STATIC context 
// where theObjectToShare is available 
A th1 = new Thread(new A(theObjectToShare)); 
... 

and Method # 2A/B:

object parentMemberVariable = ...; 

function runStuff() { 
    object _localFinal = parentMemberVariable; 
    A th1 = new Thread(new Runnable { 
    public void Run() { 
     // NON-STATIC inner classes (including anonymous) can access 
     // parents member variables. this is because there are created 
     // "in the context of" the parent class. 
     // This could also be done for the normal inner Runnables. 
     foo(parentMemberVariable); 
     // anonymous classes can also access final variables 
     // in scope at declaration 
     foo(_localFinal); 
    } 
}); 

glückliche Codierung.