2016-11-28 6 views
0

Ich habe eine 1000 * 1000 Tabelle und ein paar Threads arbeiten daran. Jeder Thread arbeitet unabhängig von einem bestimmten Teil der Tabelle und seine "Arbeit" bewegt sich mit jeder Iteration auf dem Tisch.Mehrere Threads Zugriff in Java

Anstatt die gesamte Tabelle für einen Thread zu sperren, während die anderen warten, möchte ich nur nur die benötigten Zellen für jeden Thread sperren. Also ich suche, um den benötigten "Block" von Zellen für jeden Thread zu sperren.

Meine Idee ist es, eine Sperrtabelle wie: Lock [][]gridLock=new Lock[1000][1000]; zu erstellen und die benötigten Zellen für jeden Thread zu sperren.

Dies würde mit einer gridlock(x,y,diameter) und gridUnlock(x,y,diameter) Methoden zum Sperren/Entkoppeln der benötigten Zellen gehen.

Gibt es bessere Möglichkeiten, dies zu erreichen, oder ist diese Methode geeignet?

+1

Natürlich ist es möglich, aber Sie sollten viel deutlicher angeben, was Ihre Threads tun - warum nicht jeden Thread auf einer Zeile des Tisches arbeiten lassen, und das ist es, keine Notwendigkeit für irgendeine Verriegelung. – luk2302

+1

Eine Million Schlösser werden wahrscheinlich ziemlich umständlich werden. – Kayaman

+1

Zu breit. Erfahren Sie mehr über Zugangsmuster, Zugangskosten und welche Art von Datenorganisation "Tabelle" hat. Ihr Text schlägt vor * array * oder * grid *, nicht Tabelle. Sehr wichtig ist auch, die Zugriffsarten zu bestimmen (Lesen/Schreiben). Ihr Ansatz mit 1 Million Locks wird höchstwahrscheinlich so schrecklich funktionieren, dass Single Threading schneller wäre. Ganz zu schweigen von seinem enormen Deadlocking-Potenzial. Die Sperrung kann möglicherweise größtenteils dadurch vermieden werden, dass einfach passendere Datenstrukturen ausgewählt werden. TL: DR: Es gibt viele Werkzeuge im Schuppen, aber ohne das Problem zu kennen, kann keine gute Wahl getroffen werden. – Durandal

Antwort

0

Der gleichzeitige Zugriff auf ein einzelnes Objekt wird nicht empfohlen, da dies zu einer großen Anzahl von Problemen führen kann. Das größte ist, dass das Objekt den Status ändern kann, während die Threads daran arbeiten, und dies kann die anderen Threads stören.

Wenn möglich, würde ich jeden Thread arbeiten auf seinem eigenen Objekt, den Tisch Stück für Stück und nachdem alle Threads fertig sind, konstruieren Sie die Final Table. Dadurch werden alle Threads isoliert und unnötige Nebenläufigkeitsprobleme vermieden.

Wenn die obige Methode nicht durchführbar ist. Ich würde versuchen, die Threads so unabhängig wie möglich zu halten und die Tabellendaten so weit wie möglich zu isolieren. Geben Sie jedem Thread eine Reihe von Zeilen in der zu bearbeitenden Tabelle, um sicherzustellen, dass keine Threads dieselben Teile der Tabelle ändern. Dann kann jeder Thread die Zellen in den Zeilen ändern, denen er zugewiesen wurde.

+3

Das Tabellenobjekt, das "flüchtig" ist, wird nicht viel helfen, da es nur für die Referenz für die Tabelle gilt, nicht für ihre "Zellen". – Kayaman

+0

@Kayaman ich vorschlagen, das Objekt volatil sein, da es immer noch die Möglichkeit gibt es zwei Objekte in dem CPU-Speicher zu sein, die von verschiedenen Threads modifiziert werden könnten (oder täusche ich mich?), Nicht weil seine Zellen von verschiedenen Threads geändert werden . –

+0

Es könnte Probleme mit der Sichtbarkeit geben, aber das würde sehr schäbigen Code bedeuten. Vorausgesetzt, dass die Tabelle für alle Threads ordnungsgemäß sichtbar gemacht wird, besteht kein Bedarf (oder Vorteil in der Verwendung) von "volatile". – Kayaman

0

Danke!
Ich weiß nicht, ob die Art und Weise, die ich abgeleitet habe, korrekt ist, aber das habe ich getan:
Ich habe meine Lock-Matrix wie: Lock [] [] gridLock = new Lock [1000] [1000].

Aber anstatt die ganze 1millions am Anfang sperren Initialisierung u_u, ich tue es nur, wenn wie nötig, so etwas wie:

public void lockAround(x, y, diameter){ 
[...] 
for{for{ //i and j <1000 
    gridLock[i][j]=new ReentrantLock(); 
    gridLock[i][j].lock(); 
}} 
} 


Und ich setzte sie, wenn sie in der unlockAround entsperrt auf null (x , y, Durchmesser) Methode.

+0

Dies ist falsch, wie Sie die gleichen Concurrency Probleme mit den Schleusen haben, wie Sie mit dem Tisch haben. –