尝试访问关键部分的三种类型的线程

时间:2013-06-12 15:35:54

标签: java multithreading concurrency semaphore critical-section

对于我的应用程序,我需要确定,在关键会话中只有一种类型的线程正在处理。未指定给定类型的线程数,可能是“大”。我带来了简单的解决方案:

MutableInt a,b,c;
Semaphore mutex;

void enterA() {
    while (true) {
        mutex.acquire();
        if (b.intValue() == 0 && c.intValue() == 0) {
            a.increase();
            break;
        }
        mutex.release();
    }
}

void exitA() {
    while(true) {
        mutex.acquire();
        a.decrease();
        mutex.release();
    }
}

我正在跳过异常处理,而B& C部分导致它只是复制粘贴。

它按预期工作(线程饥饿的可能性是可以的),但生成的负载太大。线程不断检查计数器。我觉得还有另一个解决方案,但想不出任何一个例子。

1 个答案:

答案 0 :(得分:1)

我不知道你的解决方案是否是问题的一部分但是我认为我会建议移动到AtomicInteger来处理所有的递增等,而不会锁定。

如果它更复杂,那么你应该考虑将AtomicReference与一些累加器类一起使用,并使用compareAndSet(...)方法以原子方式更新它。

例如,您可以将3个整数存储在MutableInts类中,并执行以下操作:

final AtomicReference<MutableInts> reference =
     new AtomicReference<MutableInts>(new MutableInts(0, 0, 0));
...
do {
   MutableInts ints = reference.get();
   // increment the ints properly which should generate a new MutableInts class
   // it should _not_ make changes to `ints` itself
   MutableInts newInts = ints.mutateSomehow(...);
   // this spins in case some other thread updated it before us here
} while (!reference.compareAndSet(ints, newInts));

所以看起来你可以用来实现这个目的的电话有限。以下是其他一些选择:

  • 每个线程更新自己的数据,然后每隔一段时间(或者可能只是在处理结束时)与中央计数器同步。相同的锁,但不经常做 lot
  • 每个线程可以更新每个线程volatile计数器,并且轮询线程可以读取计数器并更新中心信息。不确定是否允许volatile