Java 如何使用锁来确保一个方法只能同时运行一定次数
我知道在Java中,为了确保每个线程一次只运行一段代码,只需使用Java 如何使用锁来确保一个方法只能同时运行一定次数,java,multithreading,concurrency,synchronization,locking,Java,Multithreading,Concurrency,Synchronization,Locking,我知道在Java中,为了确保每个线程一次只运行一段代码,只需使用synchronized关键字。即 synchronized (getClass()) { // expensive work } 然而,我更愿意做的是在有足够的RAM可用的情况下只执行昂贵的工作。也就是说,假设我有10个线程在运行,在代码的昂贵的工作部分,它占用了50mbs的RAM。假设我根据JVM可以使用的最大内存进行计算,并意识到我可以同时安全地运行其中5个线程 那么,我如何正确地使用锁或并发或等待()/.notify
synchronized
关键字。即
synchronized (getClass()) {
// expensive work
}
然而,我更愿意做的是在有足够的RAM可用的情况下只执行昂贵的工作。也就是说,假设我有10个线程在运行,在代码的昂贵的工作部分,它占用了50mbs的RAM。假设我根据JVM可以使用的最大内存进行计算,并意识到我可以同时安全地运行其中5个线程
那么,我如何正确地使用锁
或并发
或等待()/.notify()
来确保昂贵的工作
只运行设定的次数
我希望我的问题有意义。我也研究过,但实际上我发现这个例子不起作用。在他们的例子中,似乎每个单独的线程都创建了一个lock
的实例,而在我的例子中,有多个单独的、独立的线程同时运行,它们彼此都不知道
任何人都可以给出一个例子,或者给出一个链接,指向一个使用并发/锁来满足此场景的例子吗
我需要的解决方案是Java 6兼容
那么,如何正确地使用锁、并发或.wait()/.notify()来确保昂贵的工作只运行设定的次数
泰勒就是为这种事情而做的。它有一定数量的许可证,除非有许可证,否则螺纹会堵塞
引自:
计数信号灯。从概念上讲,信号量维护一组许可。如果需要,每个acquire()都会阻塞,直到有许可证可用,然后再获取它。每次释放()都会添加一个许可证,可能会释放阻止收单机构。但是,没有使用实际的许可证对象;信号量只保留可用数量的计数,并相应地进行操作
类似于以下代码的代码应该可以工作:
// 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();
}
那么,如何正确地使用锁、并发或.wait()/.notify()来确保昂贵的工作只运行设定的次数
泰勒就是为这种事情而做的。它有一定数量的许可证,除非有许可证,否则螺纹会堵塞
引自:
计数信号灯。从概念上讲,信号量维护一组许可。如果需要,每个acquire()都会阻塞,直到有许可证可用,然后再获取它。每次释放()都会添加一个许可证,可能会释放阻止收单机构。但是,没有使用实际的许可证对象;信号量只保留可用数量的计数,并相应地进行操作
类似于以下代码的代码应该可以工作:
// 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();
}
伟大的是否应该在父线程中声明信号量变量(从而使变为volatile
和static
)?我将使它成为您试图保护的类的私有final。如果您试图保护一个静态
方法,那么它应该是类的静态
。您不需要将它设置为volatile,我也不会在线程中声明它。这个类应该保护自己。如果你想保护一个类的多个实例,那么你需要使信号量也是静态的。谢谢你现在的尝试。我这样做是为了动态计算创建int-maxThreadsForProcessing=(int)Runtime.getRuntime().maxMemory()/1024/1024/70的许可数量现在代码>和测试它似乎已经工作了!尽管如此,计算出每台机器作为内存函数的精确锁数将是一门艺术。但我喜欢这个新工具:)太棒了!是否应该在父线程中声明信号量变量(从而使变为volatile
和static
)?我将使它成为您试图保护的类的私有final。如果您试图保护一个静态
方法,那么它应该是类的静态
。您不需要将它设置为volatile,我也不会在线程中声明它。这个类应该保护自己。如果你想保护一个类的多个实例,那么你需要使信号量也是静态的。谢谢你现在的尝试。我这样做是为了动态计算创建int-maxThreadsForProcessing=(int)Runtime.getRuntime().maxMemory()/1024/1024/70的许可数量现在代码>和测试它似乎已经工作了!尽管如此,计算出每台机器作为内存函数的精确锁数将是一门艺术。但我喜欢这个新工具:)