代码之家  ›  专栏  ›  技术社区  ›  E.S.

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

  •  1
  • E.S.  · 技术社区  · 12 年前

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

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

    然而,我宁愿做的只是在有足够RAM的情况下执行昂贵的工作。也就是说,假设我有10个线程在运行 expensive work 它占用了50 MB的RAM。假设我根据JVM可以使用的最大内存进行计算,并意识到我可以同时安全地运行其中5个线程。

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

    我希望我的问题有道理。我已经调查过了 Locks 以及 ReentrantLock 但实际上我发现这个例子不起作用。在他们的例子中,似乎每个单独的线程都创建了 lock 在我的情况下,我有多个单独的、独立的线程同时进行,而它们并不知道彼此。

    有人能给出一个例子吗?或者提供一个链接到一个例子,在这个例子中,你使用并发/锁定来满足这个场景?

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

    1 回复  |  直到 12 年前
        1
  •  8
  •   Gray droiddeveloper    12 年前

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

    这个 Semaphore 泰勒就是为这种事情而生的吗。它有一定数量的许可证,除非有许可证,否则线程将阻塞。

    引用 javadocs :

    计数信号灯。从概念上讲,信号量维护一组许可。如果需要,每个Acquired()都会阻止,直到有许可证可用,然后再获取。每个release()都添加了一个许可证,可能会释放一个阻止的acquirer。然而,没有使用实际的许可对象;信号量只是保持对可用数字的计数并相应地进行操作。

    下面的代码应该可以工作:

    // 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();
    }