1

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

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 部分导致它只是复制粘贴。

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

4

1 回答 1

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

因此,您可以用来完成此任务的调用似乎受到限制。以下是一些其他选择:

  • 每个线程更新自己的数据,然后每隔一段时间(或者可能只是在处理结束时)与中央计数器同步。相同的锁,但做的次数少得多。
  • 每个线程都可以更新每个线程的volatile计数器,而轮询线程可以读取计数器并更新中心信息。不确定是否volatile允许。
于 2013-06-12T15:40:02.857 回答