我有一个需求,我有一个多线程java应用程序,我想监控应用程序中的内存使用情况。我想在内存超过90%时暂停执行器服务中所有正在运行的线程。下面是一个示例代码,我已经写了,但是,我不确定,如何暂停线程。我试图每分钟轮询一次,以检查内存利用率,但不确定如何暂停执行器服务中的所有线程。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class PauseThreads {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for(int i=0;i<10;i++){
exec.submit(new Workers());
}
ScheduledExecutorService schedule = (ScheduledExecutorService) Executors.newSingleThreadExecutor();
schedule.scheduleAtFixedRate( new Runnable(){
@Override
public void run() {
Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory();
long allocatedMemory = runtime.totalMemory();
if( (allocatedMemory / maxMemory ) > 0.9 ){
//pause all the threads running under the exec
}
}
}, 0, 60, TimeUnit.SECONDS);
}
}
class Workers implements Runnable{
@Override
public void run() {
// do some work
}
}
请建议,需要做什么改变,或者是否有其他更好的方法。谢谢。
您可以使用以下示例中的ReentrantLock
。您的Worker
线程需要偶尔调用check()
方法
public class MemoryAwait {
private Lock lock = new ReentrantLock();
private Condition memoryAvailable = lock.newCondition();
public MemoryAwait() {
ScheduledExecutorService schedule = (ScheduledExecutorService) Executors.newSingleThreadExecutor();
schedule.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
if (enoughFreeMemory()) {
memoryAvailable.notify();
}
}
}, 0, 60, TimeUnit.SECONDS);
}
public void check() throws InterruptedException {
try {
lock.lock();
while (!enoughFreeMemory()) {
memoryAvailable.await();
}
} finally {
lock.unlock();
}
}
private boolean enoughFreeMemory() {
Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory();
long allocatedMemory = runtime.totalMemory();
return allocatedMemory / maxMemory < 0.9;
}
}
我不知道如何监控堆的使用情况,但是…
…你说"暂停"就像一个线程要对另一个线程做什么。
坏主意。
如果你是一个线程,你占用了所有的内存,如果我可以"暂停"你会有什么好处?当你处于"暂停"状态时,你如何释放你正在使用的内存?"
你想让每个工作线程做这样的事情:
while (true) {
waitUntilTheresEnoughAvailableResources();
acquireSomeResources();
doAUnitOfWorkWork();
freeResources();
}