2012-09-25 10 views
5

簡介:多線程通信:使用AtomicInteger等原子變量有多好?爲什麼沒有AtomicFloat?

我想創建一個多線程的Android應用程序。我的問題是線程之間的溝通。我讀過關於線程之間的通信,並且我遇到了像Looper/Handler設計這樣的東西,這似乎與AtomicInteger非常相關,Atomic變量等。現在,我使用AtomicInteger作爲通信,但由於我對Java的經驗不是很豐富,我不確定在我的情況下這是否不好,或者針對我的特定目的是否有更好的解決方案。當我注意到我實際上需要像AtomicFloat這樣的東西時,我也對我的方法有點懷疑,但它不存在。我覺得我很想念這個概念。我也發現你可以讓自己成爲一個AtomicFloat,但我只是不確定我是否在正確的路上或者是否有更好的技術。

問題: 可以使用Atomic Variables並且爲我的特定目的實現AtomicFloat(如下所述)還是有更好的方式來處理通信?使用AtomicVariables迄今爲止應用的

用途/建築:

我有4個線程有以下目的:

1.SensorThread:讀取傳感器數據和AtomicVariables保存最近一次的值如

AtomicFloat gyro_z,AtomicFloat gyro_y, ... 

2.CommunicationThread:與PC通信,解釋來自套接字的命令並設置應用的狀態AtomicInteger: AtomicInteger狀態;

3.UIThread:從 AtomicFloat gyro_z,AtomicFloat gyro_y,

4.ComputationThread顯示當前的傳感器值:使用傳感器值AtomicFloat gyro_z,AtomicFloat gyro_y, ...和狀態AtomicInteger state進行計算並通過USB發送命令。

+0

這聽起來像你可以做一個易變的浮動。 – assylias

+0

請看看這篇文章: http://stackoverflow.com/questions/5505460/java-is-there-no-atomicfloat-or-atomicdouble –

+0

@Perroloco,我讀了,但較低的兩個回覆他們說那個人真的很少見。對我來說,AtomicFloat應該存在是非常合乎邏輯的。那爲什麼我質疑我對他們的使用 –

回答

1

你基本上有一個讀者的作家概率lem,有兩位讀者和(目前)只有一位作家。如果你只是想在線程之間傳遞簡單的類型,那麼AtomicInteger或類似實現的AtomicFloat將會很好。

然而,更適應的解決方案,這將使您能夠處理更復雜的數據類型的工作將是一個ReadWriteLock中保護,你讀或寫你的對象數據的代碼:

如:

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(); 
    } 
} 

這隻會啓用「僅限一名作者」或「多個讀者」場景來訪問共享對象。

這將使您例如具有複雜型,看起來像這樣工作的:當使用如果兩個字段設置和修改安全,原子,你應該關心這個數據類型

public class SensorRead { 

    public java.util.Date dateTimeForSample; 

    public float value; 

} 

。 AtomicXXX類型的對象不再有用。

+0

謝謝,我想我可以堅持我的原子變量計劃。 –

0

你必須先問自己,你是否真的需要理論上的功能AtomicFloat。你可以通過簡單的volatile float得到的唯一好處是compareAndSetaddAndGet操作(因爲我猜想在浮點數的情況下增量和減量並沒有什麼意義)。

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

現在,這裏唯一的問題是,compareAndSet使用特定於平臺的調用,不爲花車存在:

如果你真的需要這些,你也許可以通過研究AtomicInteger例如代碼實現它們,所以你可能需要使用Float.floatToIntBits方法來獲得一個int效仿它,然後使用CAS的AtomicInteger,是這樣的:

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; 
    } 
} 
相關問題