2017-06-03 3 views
3

Ist der folgende Code Thread-Safe bei gleichzeitigem Zugriff auf List?
Addiert der Volatile hier einen Wert?Boolean zum Synchronisieren verwenden

class concurrentList{ 

     private AtomicBoolean locked = new AtomicBoolean(true); 
     volatile List<Integer> list=new LinkedList<Integer>(); 
     long start = System.currentTimeMillis(); 
     long end = start + 60*100; 


     public void push(int e){ 
      while(!locked.get()); 
      list.add(e); 
      while(!locked.compareAndSet(true,false)); 
     } 

     public int pop(){ 
      int elem; 
      while(locked.get()); 
      elem=(Integer)list.remove(0); 
      while(!locked.compareAndSet(false,true)); 
      return elem; 
     } 
.... 
} 
+0

Nicht sicher, warum Sie unterschiedliche Sperrbedingungen in der Push- und Pop-Methode haben. Aber abgesehen davon, warum nicht eine ['java.util.concurrent.Lock'] (https://docs.oracle.com/javase/lock/docs/api/java/util/concurrent/locks/Lock.html ? ist-extern = true) Objekt? – n247s

Antwort

2

Nein, es ist nicht threadsicher. Zwei Threads, die push() aufrufen, können perfekt sowohl das Gesperrte als wahr lesen als auch gleichzeitig zu der verknüpften Liste hinzufügen. Da eine LinkedList nicht threadsicher ist, ist Ihr Code nicht Thread-sicher.

Verwenden Sie zum Sperren ein Schloss und kein AtomicBoolean.

+0

Genau, plus eins für die konkrete und schnelle Antwort –

0

In diesem besonders Fall würde ich für die Methoden synchronisiert und für die Variable nicht flüchtig nach [this question][1]

Klasse concurrentList {

private AtomicBoolean locked = new AtomicBoolean(true); 
    List<Integer> list=new LinkedList<Integer>(); 
    long start = System.currentTimeMillis(); 
    long end = start + 60*100; 


    public synchronized void push(int e){ 
     while(someLock.notCondition()); //only an example 
     list.add(e); 
     someLock.notify(); 
    } 

    public synchronized int pop(){ 
     int elem; 
     while(someLock.notCondition()); 
     elem=(Integer)list.remove(0); 
     someLock.notify() 
     return elem; 
    } 
.... 
} 
+0

Was ist 'someLock'? – saka1029

1

Inn solchen Fällen I ReadWriteLock Verwendung empfehlen würde. Diese Sperre hat zwei Anwendungen. Wenn readLock auf, keine Lesevorgänge sind erlaubt, soweit nicht Schreibsperre ist released.Read Sperre nicht blockierende ist:

class concurrentList{ 
    ReadWriteLock lock =new ReentrantReadWriteLock(); 

    private AtomicBoolean locked = new AtomicBoolean(true); 
    volatile List<Integer> list=new LinkedList<Integer>(); 
    long start = System.currentTimeMillis(); 
    long end = start + 60*100; 


    public void push(int e){ 
     lock.writeLock().lock(); 
     try{ 
      list.add(e); 
     } finally { 
      lock.writeLock().unlock(); 
     } 
    } 

    public int pop(){ 
     lock.readLock().lock(); 
     try { 
     int elem; 

     elem=(Integer)list.remove(0); 
     } finally { 
      lock.readLock().unlock(); 
     } 
     return elem; 
    } 

.... }

0

mehr Hinzufügen Für jede gleichzeitige in Antwort dh bereits hinzugefügt drei Konzepte der Programmierung, müssen Sie prüfen, während ein Thread sichere Programmierung Schreiben .Wenn ein konkurrierendes Programm ist nicht richtig geschrieben, neigen dazu, die Fehler in einer der drei Kategorien zu fallen: Aomicity, Sichtbarkeit oder Bestellung.

Atomicity: Angebote mit denen Aktionen und Sätze von Aktionen unteilbar effects.It haben in der Regel gedacht hinsichtlich der gegenseitigen Ausgrenzung.

Sichtbarkeit: Bestimmt, wann die Effekte eines Threads von einem anderen gesehen werden können.

Bestell: Bestimmt, wann Aktionen in einem Thread gesehen werden kann

In Ihrem Code Erste Ausgabe an einen anderen Bezug aus, um auftreten es oben concepts.You erwähnt versagt nicht Schloss, so dass die Sichtbarkeit und Bestellung sind nicht gewährleistet. Für Thread-Safe können Sie in gleichzeitige API.Oder gibt es nicht blockierende Linked-List, die compareAndset verwenden wird.

Verwandte Themen