多线程状态感知变量

时间:2013-07-06 17:33:26

标签: java multithreading

假设我有一种方法可以高速处理实时事件消息。

对于每个呼叫(消息通过),我有多个我想要跟踪的状态,我在下次调用方法时所做的处理类型取决于当前状态。

因为它的速率很高并且可能需要一些时间来处理并且在一个线程上,所以之前的调用可能在下一个调用之前没有完成。

如果我为每个方法调用使用异步多线程实现(例如线程池),那么可以同时执行多个调用,并且每个调用将评估为相同的状态,并且相同类型的处理将发生,这不是我想要的。我想确保如果在其中一个线程调用中更改了变量的状态,那么其他线程将知道该状态。

我的问题是这个场景的最佳类型实现(使用原子整数?同步?)对于我想确保其异步处理速率和每次调用处理的情况,但同时时间想要确保在“同一时间”对线程的多次调用是状态感知的。订单并不是那么重要。

即:

state = false;//current state

a thread                     b thread (and vice versa if thread b or thread a "saw" it first)
------------------------------
|                            |
|                            |
sees false                  sees false (should "see" true)
changes to true             changes to true (should not change to true)
|                            |


void processMessage(String message) {
    Runnable runner = new Runnable() {
       void run() {
        if(track.in_state == true) {
          if(track.state == 1) {
             track.in_state = false;
             //do something here
          }
          else if(track.state == 2) {
             track.in_state = false;
             //do something here
          }
        }
      }
    }
    poolA.executor(runner);
    //what happens here is that multiple threads are executed with same processing here
}

void processADifferentMessage(String message) {//a different but also dependent on the state tracker object
    Runnable runner = new Runnable() {
       void run() {
        if(track.in_state == false) {
             //do something here
        }
       }
    };
    //I also want to make sure that its state aware here as well in this thread pool
    poolB.executor(runner);
}

感谢您的回复。

2 个答案:

答案 0 :(得分:0)

您可以使用AtomicBoolean运营商使用AtomicIntegercompareAndSet

AtomicBoolean atomicBoolean;
AtomicInteger atomicInteger;
void processMessage(String message) {
    Runnable runner = new ... {
        boolean success = false;
        boolean boolState;
        int intState;
        while(!success) {
            boolState = atomicBoolean.get();
            success = atomicBoolean.compareAndSet(boolState, !boolState);
        }
        success = false
        while(!success) {
            intState = atomicInteger.get();
            success = atomicInteger.compareAndSet(intState, (intState + 1) % maxIntState);
        }
        if(boolState) {
          if(intState == 1) {
             //do something here
          }
          else if(intState == 2) {
             //do something here
          }
        }
    }
    poolA.executor(runner);
}

while循环读取AtomicBooleanAtomicInteger的状态并将其更新为新状态 - 我假设您翻转了AtomicBoolean的状态每次都在true和false之间,并且您将AtomicInteger初始化为0,然后递增它直到达到maxIntState,此时您将其重置为0(例如,如果maxIntState为4,然后AtomicInteger将从0 - > 1 - > 2 - > 3 - > 0)。你在这里使用while循环,以防另一个线程在你读取状态的时间和你尝试更新状态的时间之间改变了状态(例如你可能读取intState为1,但是在另一个帖子更新之前,另一个帖子会将intState更新为2,然后再次尝试使用intState 2)

答案 1 :(得分:0)

您所说的当前问题可能可以通过使用AtomicInteger和AtomicBoolean来解决。

但我想你需要某种类型的异步模型,你需要根据某些状态处理/处理某些消息,并且它们可能会根据某些状态同时执行。对于这些类型的情况,lock / synchronized比使用原子版本更好,因为您可能需要使用wait / notify / await / signal,具体取决于您无法使用atomicInteger和AtomicBoolean执行的某些状态。您的要求可能会更进一步。