如何使用锁来确保方法只能同时运行一定次数

E.S*_*.S. 1 java concurrency multithreading synchronization locking

我知道在Java中,为了确保每个线程一次只运行一段代码,只需使用synchronized关键字.也就是说,

synchronized (getClass()) {
   // expensive work
}
Run Code Online (Sandbox Code Playgroud)

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

所以,我如何使用LocksConcurrency.wait()/.notify()适当,以确保expensive work只运行的次数,组数?

我希望我的问题有道理.我已经研究过LocksReentrantLock,但实际上我发现这个例子不起作用.在他们的例子中,似乎每个单独的线程创建了一个实例,lock在我的情况下,我有多个独立的,独立的线程同时进行,他们不知道彼此.

任何人都可以给出一个示例,或者给出一个使用Concurrency/Locks来满足这种情况的示例的链接吗?

我需要解决方案兼容Java 6.

Gra*_*ray 8

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

Semaphore是泰勒这样的事情做.它有一定数量的许可证,除非有许可证,否则线程将被阻止.

引用javadocs:

计数信号量.从概念上讲,信号量保持一组许可.如果需要,每个acquire()都会阻止,直到有许可证可用,然后接受它.每个release()都会添加一个许可证,可能会释放一个阻塞收单器.但是,没有使用实际的许可对象; 信号量只保留可用数量并相应地采取行动.

类似下面的代码应该工作:

// 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();
}
Run Code Online (Sandbox Code Playgroud)