1

我知道在 Java 中,要确保每个线程一次只运行一段代码,只需使用synchronized关键字即可。IE,

synchronized (getClass()) {
   // expensive work
}

但是,我宁愿只在有足够 RAM 可用的情况下执行昂贵的工作。即,假设我有 10 个线程正在运行,并且在expensive work代码部分中,它占用了 50 MB 的 RAM。假设我根据 JVM 可以使用的最大内存进行计算,并意识到我可以安全地同时运行 5 个这些线程。

那么,我怎样才能正确使用LocksorConcurrency.wait()/.notify()确保expensive work仅运行该设定次数?

我希望我的问题是有道理的。我研究了LocksReentrantLock,但实际上我发现这个例子不起作用。在他们的示例中,似乎每个单独的线程都创建了一个实例,lock在我的情况下,我有多个单独的、独立的线程同时运行并且它们彼此不知道。

任何人都可以举一个例子,或者给出一个使用并发/锁来满足这种情况的例子的链接吗?

我需要该解决方案与 Java 6 兼容。

4

1 回答 1

8

那么,我如何正确使用 Locks 或 Concurrency 或 .wait()/.notify() 来确保昂贵的工作只运行设定的次数?

Semaphore是泰勒为这类事情而设计的。它有一定数量的许可,除非许可可用,否则线程将阻塞。

引用javadocs

计数信号量。从概念上讲,信号量维护一组许可。如有必要,每个 acquire() 都会阻塞,直到获得许可,然后再接受它。每个 release() 添加一个许可,可能会释放一个阻塞的获取者。但是,没有使用实际的许可对象;Semaphore 只是对可用数量进行计数并采取相应措施。

类似以下代码的东西应该可以工作:

// only allow 5 threads to do the expensive work at the same time
private final Semaphore semaphore = new Semaphore(5, true /* fairness */);
...
// this will block if there are already 5 folks doing the expensive work
semaphore.acquire();
try {
   doExpensiveWork();
} finally {
   // always do the release in a try/finally to ensure the permit gets released
   // even if it throws
   semaphore.release();
}
于 2013-09-06T18:09:15.970 回答