У меня есть вопрос Java mulithreading. У меня есть следующий класс работника:Проблемы с кучей Java ExecutorService
public class ThreadWorker implements Runnable {
//some code in here
public void run(){
// invokes some recursion method in the ThreadWorker itself,
// which will stop eventually
{
}
Для работы с потоками Я использую ExecutorService
:
public static int THREAD_NUMBER = 4;
public static ExecutorServide es = Executors.newFixedThreadPool(THREAD_NUMBER);
Добавления экземпляров класса ThreadWroker
происходит здесь:
public void recursiveMethod(Arraylist<Integers> elements, MyClass data){
if (elements.size() == 0 && data.qualifies()){
ThreadWorker tw = new ThreadWorker(data);
es.execute(tw);
return;
}
for (int i=0; i< elements.size(); i++){
// some code to prevent my problem
MyClass data1 = new MyClass(data);
MyClass data2 = new MyClass(data);
ArrayList<Integer> newElements = (ArrayList<Integer>)elements.clone();
data1.update(elements.get(i));
data2.update(-1 * elements.get(i));
newElements.remove(i);
recursiveMethod(newElements, data1);
recursiveMethod(newElements, data2);
{
}
Проблема заключается в том что глубина рекурсивного дерева довольно велика, так как это ширина, поэтому в добавлено много ThreadWorkers
, поэтому через некоторое время на би г ввести получить
Exception in thread "pool-1-thread-2" java.lang.OutOfMemoryError: Java heap space
, которое вызывается, как я думаю, что из-за Ginormous числа ThreadWorkers
я добавляю к ExecutorSirvice
быть выполнена, так что бежит из памяти. Каждый ThreadWorker
занимает около 40 МБ ОЗУ для всех, в чем он нуждается.
Есть ли способ, чтобы узнать, сколько потоков (экземпляров классов, реализующих runnable interface) было добавлено в ExecutorService
? Так что я могу добавить его в показанный выше код (интермедиат «// некоторый код, чтобы предотвратить мою проблему»), так как
while ("number of threads in the ExecutorService" > 10){
Thread.sleep(10000);
}
, так что я не буду вдаваться в глубокие или широкие с моей рекурсии и предотвратить те ситуации исключения.
С уважением, Сергей Аганезов младший.
Создать 'TreadPoolExecutor эс = новый ThreadPoolExecutor (4, 4, 10000, TimUnit.MILLISECONDS, новый ArrayBlockingQueue (10));' , а затем установить rejectedHandler к нему 'es.setRejectedExecutionHandler (новый ThreadPoolExecutor .CallerRunsPolicy()); '. После этого, если я это правильно понимаю, он справится с моей проблемой, так как количество запущенных потоков достигает 4, а количество потоков в очереди достигает 10, следующая добавленная задача будет отклонена и будет выполняться основной поток, останавливая все остальные деятельность в нем. –
Да, это так. – ulmangt