我目前有以下设置。在运行一段时间之后,我得到了内存异常;我怀疑main中的for循环导致了太多的备份方法调用。如果我不想增加线程池大小,那么限制调用的最佳方法是什么?
public class ManagedThreads {
private final static ExecutorService ex = Executors.newFixedThreadPool(10);
public static void myMethod(final int i) {
ex.execute(new Runnable() {
public void run() {
// method body using i
}
});
}
public static void main(String[] args) {
for (int i = 0; i < 1000000000; ++i)
myMethod(i);
}
}
修改
我的意思是表明我将循环索引传递给runnables。
答案 0 :(得分:1)
你有10个线程,所以添加10个作业,你永远不会为了安排它们而耗尽内存。
e.g。
public class ManagedThreads {
private final static ExecutorService ex = Executors.newFixedThreadPool(10);
public static void myMethod(final int i) {
ex.execute(new Runnable() {
public void run() {
// do every tenth task.
for(int j = i; j < 1000000000; j += 10) {
// method body
}
}
});
}
public static void main(String[] args) {
for (int i = 0; i < 10; ++i)
myMethod(i);
}
}
答案 1 :(得分:1)
我在运行一段时间之后就出现了内存异常;我怀疑main中的for循环导致了太多的备份方法调用。如果我不想增加线程池大小,那么限制调用的最佳方法是什么?
这是常见问题解答。请在此处查看我的回答:Process Large File for HTTP Calls in Java
您需要定义自己的有界作业队列,然后定义RejectedExecutionHandler
。以下代码在尝试向作业队列添加超过100个作业时将阻止。
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(100);
ThreadPoolExecutor threadPool =
new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, queue);
// we need our RejectedExecutionHandler to block if the queue is full
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
// this will block the producer until there's room in the queue
executor.getQueue().put(r);
} catch (InterruptedException e) {
throw new RejectedExecutionException(
"Unexpected InterruptedException", e);
}
}
});
答案 2 :(得分:0)
我会这样做(它将允许每个工作人员在cpu时钟方面执行相同数量的工作)
private final static ExecutorService ex = Executors.newFixedThreadPool(10);
final static AtomicInteger counter = new AtomicInteger(0);
public static void myMethod(final int i) {
ex.execute(new Runnable() {
public void run() {
while (counter.getAndIncrement() < 1000000000) {
//method body
}
}
});
}
public static void main(String[] args) {
for (int i = 0; i < 10; ++i)
myMethod(i);
}
}
如彼得所建议的那样,每个工人的增量为10。节省了大量物体,处理速度也很快。