2012-04-08 6 views
2

Java mulithreading 질문이 있습니다. 여기에 발생 ThreadWroker 클래스의Java ExecutorService 힙 공간 문제

public static int THREAD_NUMBER = 4; 
public static ExecutorServide es = Executors.newFixedThreadPool(THREAD_NUMBER); 

추가 인스턴스 :

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);  
    {  
} 

문제가

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 사용하고 스레드로 작업하기 : 나는 다음과 같은 작업자 클래스가 재귀 트리의 깊이가 꽤 넓기 때문에 너비가 넓으므로 ThreadWorkersExecutorService에 추가되므로 잠시 후에 g를 입력 할 발생

Exception in thread "pool-1-thread-2" java.lang.OutOfMemoryError: Java heap space 

, 나는 때문에 내가 실행되는 ExecutorSirvice에 추가 해요 ThreadWorkers의 ginormous 한 수, 생각대로 메모리가 부족하므로를 얻을. 모든 ThreadWorker은 필요에 따라 약 40MB의 RAM을 필요로합니다.

ExecutorService에 몇 개의 스레드 (실행 가능한 인터페이스를 구현하는 클래스의 인스턴스)를 추가 할 수있는 방법이 있습니까? 그래서,

while ("number of threads in the ExecutorService" > 10){ 
    Thread.sleep(10000); 
} 

으로 내가 내 재귀 깊은 또는 광범위한으로 이동하는 것을 방지하지 않습니다 (이하 "// 내 문제를 방지하기 위해 몇 가지 코드는"INT) 코드 위에 표시에 추가 할 수 있습니다 예외 상황을 던집니다.

감사합니다. Sergey Aganezov jr.

답변

6

ThreadPoolExecutor.CallerRunsPolicy을 사용하여 BlockingQueue으로 백업 된 ThreadPoolExecutor을 생성하는 것은 어떻습니까?

이렇게하면 작업을 실행할 수있는 작업자 스레드가없는 경우 주 스레드 (새 작업 추가 중)가 작업 자체를 실행하므로 더 이상 작업을 추가 할 수 없습니다.

해당 Javadoc 페이지의 ThreadPoolExecutor에 대한 생성자 옵션에 대한 자세한 내용이 있습니다.

+0

'TreadPoolExecutor ES = 새로운 ThreadPoolExecutor에 (4, 4, 10000, TimUnit.MILLISECONDS 새로운 ArrayBlockingQueue를 (10))를 작성 .CallerRunsPolicy());'. 그렇다면 제대로 이해하면 문제가 발생합니다. 실행중인 스레드의 수가 4 개가되고 대기열에있는 스레드의 수가 10에 도달하면 다음에 추가 된 작업이 거부되어 메인 스레드가 수행되어 다른 스레드 그것의 활동. –

+0

네, 맞습니다. – ulmangt

1

당신의 경우는 Java JDK의 "fork-join"프레임 워크와 잘 맞다고 생각합니다. (해당 키워드의 Google)

포크 - 조인 (Fork-Join)은 가능한 한 "분할"을 지연하여 대기열에있는 작업 수를 줄이는데 도움이됩니다.

코드를 철학에 맞게 재구성해야합니다. 다음` 하고 rejectedHandler로 설정 `es.setRejectedExecutionHandler (사용해, 새로운 ThreadPoolExecutor;

관련 문제