2012-09-25 3 views
5

Intro:Multithread-Kommunikation: Wie gut ist die Verwendung von Atomvariablen wie AtomicInteger? Warum gibt es kein AtomicFloat?

Ich möchte eine Multithread-Android-App erstellen. Mein Problem ist die Kommunikation zwischen den Threads. Ich las über die Kommunikation zwischen Threads und stieß auf Dinge wie das Looper/Handler-Design, das ziemlich involviert schien und Atomic-Variablen wie AtomicInteger. Für den Moment habe ich AtomicInteger als Kommunikation benutzt, aber da ich in Java nicht sehr erfahren bin, bin ich nicht sicher, ob das in meinem Fall schlecht ist/ob es eine bessere Lösung für meinen speziellen Zweck gibt. Ich wurde auch ein wenig misstrauisch gegenüber meiner Methode, als ich bemerkte, dass ich eigentlich etwas wie AtomicFloat brauche, aber es ist nicht vorhanden. Ich fühlte mich, als missbrauche ich das Konzept. Ich habe auch festgestellt, dass du dich zu einer AtomicFloat machen kannst, aber ich bin mir nicht sicher, ob ich auf dem richtigen Weg bin oder ob es eine bessere Technik gibt.

Frage: Ist es in Ordnung/gut atomare Variablen zu verwenden und auch AtomicFloat für meinen speziellen Zweck (unten beschrieben) zu implementieren oder gibt es einen besseren Weg, die Kommunikation zu handhaben?

Zweck/Architektur der App AtomicVariables mit bisher:

Ich habe 4 Themen mit folgendem Zweck:

1.SensorThread: Sensordaten liest und speichert die letzten Werte in AtomicVariables wie

AtomicFloat gyro_z,AtomicFloat gyro_y, ... 

2.CommunicationThread: die Kommunikation mit dem PC, interpretiert Befehle, die die Buchse kommen bilden und den Zustand der App in Bezug gesetzt eines AtomicIntegers: AtomicInteger Zustand;

3.UIThread: Zeigt den aktuellen Sensorwerte von AtomicFloat gyro_z, AtomicFloat gyro_y,

4.ComputationThread: AtomicFloat gyro_z,AtomicFloat gyro_y, ... verwendet Sensorwerte und Zustands AtomicInteger state Berechnung auszuführen und die Befehle über USB zu senden.

+0

Es klingt wie Sie könnten mit einem flüchtigen Schwimmer tun. – assylias

+0

Bitte nehmen Sie sich einen Blick auf diesen Beitrag: http://stackoverflow.com/questions/5505460/java-is-there-no-atomicfloat-or-atomicdouble –

+0

@Perroloco ich das las, aber die unteren zwei Antworten Ich sagte, dass man das wirklich selten benutzt. Es erschien mir sehr logisch, dass AtomicFloat existiert. das, warum ich meine Verwendung von ihnen in Frage gestellt –

Antwort

1

Sie haben im Grunde einen Leser Schriftsteller prob:, so dass Sie wahrscheinlich es mithilfe der Float.floatToIntBits Methode emulieren müssen einen int erhalten, dann das CAS von AtomicInteger, so etwas wie verwenden lem, mit zwei Lesern und (im Moment) nur einem Schreiber. Wenn Sie nur einfache Typen zwischen Threads übergeben möchten, ist ein AtomicInteger oder ein ähnlich implementiertes AtomicFloat in Ordnung.

jedoch eine Aufnahmelösung, die es Ihnen ermöglichen würde, mit komplexeren Datentypen zu arbeiten, würde eine ReadWriteLock, den Code zu schützen, wo Sie Ihre Objektdaten lesen oder schreiben:

zB:

private ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); //the reentrant impl 

.... 

public void readMethod() { 

    readWriteLock.readLock().lock(); 

    try { 
     //code that simply _reads_ your object 
    } finally { 
     readWriteLock.readLock().unlock(); 
    } 

} 

public void writeMethod() { 

    readWriteLock.writeLock().lock(); 

    try { 
     //... code that modifies your shared object/objects 
    } finally { 
     readWriteLock.writeLock().unlock(); 
    } 
} 

Dies aktiviert nur Szenarien mit "nur einem Writer" oder "mehreren Lesern" für den Zugriff auf Ihre gemeinsamen Objekte.

Sie Dies würde es ermöglichen, zum Beispiel mit einer komplexen Art zu arbeiten, die wie folgt aussieht:

public class SensorRead { 

    public java.util.Date dateTimeForSample; 

    public float value; 

} 

Während dieses Datentyp verwenden Sie, wenn die beiden Felder sicher und atomar festgelegt und geändert kümmern sollten. Die AtomicXXX-Typ-Objekte sind nicht mehr nützlich.

+0

danke, ich denke, ich kann bei meinem atomaren variablen Plan bleiben. –

0

Sie müssen sich zuerst fragen, ob Sie wirklich die Funktionalität eines theoretischen AtomicFloat benötigen. Der einzige Vorteil, den Sie über eine einfache volatile float haben könnten, ist die compareAndSet und die Operationen (da ich denke, Inkrement und Dekrement sind nicht wirklich sinnvoll im Falle von Floats).

Wenn Sie wirklich diejenigen brauchen, könnten Sie wahrscheinlich sie implementieren, indem Sie den Code AtomicInteger zB Studium:

public final int addAndGet(int delta) { 
    for (;;) { 
     int current = get(); 
     int next = current + delta; 
     if (compareAndSet(current, next)) 
      return next; 
    } 
} 

Jetzt hier das einzige Problem ist, dass compareAndSet verwendet plattformspezifische Anrufe, die für Schwimmer nicht existieren

private volatile float value; 

public final boolean compareAndSet(float expect, float next) { 
    AtomicInteger local = new AtomicInteger(); 
    for(;;) { 
     local.set(Float.floatToIntBits(value)); 
     if(local.compareAndSet(Float.floatToIntBits(expect), 
           Float.floatToIntBits(next)) { 
      set(Float.intBitsToFloat(local.get())); 
      return true; 
     } 
    } 
} 

public final float addAndGet(float delta) { 
    for (;;) { 
     float current = get(); 
     float next = current + delta; 
     if (compareAndSet(current, next)) 
      return next; 
    } 
} 
Verwandte Themen