문제

내가 찾는 가장 간단 간단한 방법으로 구현하는 다음과 같다:

  • 주요 프로그램으로 인스턴스화하는 작업자 스레드가 수행하는 작업입니다.
  • n 작업 실행할 수 있다.
  • n 에 도달하면,더 이상 노동자 시작 카운트까지의 실행 스레드가 다시 아래 방울 n.
도움이 되었습니까?

해결책

내 생각에는 executors.newfixedthreadpool 요구 사항에 맞습니다. 결과를 메인 스레드로 반환 할 것인지 또는 작업이 완전히 자체 포함되어 있는지 여부에 따라 결과 ExecutorService를 사용하는 여러 가지 방법이 있습니다. 일부 이벤트에 대한 응답으로 작업이 대기되는지 여부.

  Collection<YourTask> tasks = new ArrayList<YourTask>();
  YourTask yt1 = new YourTask();
  ...
  tasks.add(yt1);
  ...
  ExecutorService exec = Executors.newFixedThreadPool(5);
  List<Future<YourResultType>> results = exec.invokeAll(tasks);

또는 일부 이벤트에 대한 응답으로 수행 할 새로운 비동기 작업이있는 경우 ExecutorService의 Simple을 사용하고 싶을 것입니다. execute(Runnable) 방법.

다른 팁

/* Get an executor service that will run a maximum of 5 threads at a time: */
ExecutorService exec = Executors.newFixedThreadPool(5);
/* For all the 100 tasks to be done altogether... */
for (int i = 0; i < 100; i++) {
    /* ...execute the task to run concurrently as a runnable: */
    exec.execute(new Runnable() {
        public void run() {
            /* do the work to be done in its own thread */
            System.out.println("Running in: " + Thread.currentThread());
        }
    });
}
/* Tell the executor that after these 100 steps above, we will be done: */
exec.shutdown();
try {
    /* The tasks are now running concurrently. We wait until all work is done, 
     * with a timeout of 50 seconds: */
    boolean b = exec.awaitTermination(50, TimeUnit.SECONDS);
    /* If the execution timed out, false is returned: */
    System.out.println("All done: " + b);
} catch (InterruptedException e) { e.printStackTrace(); }

executors.newfixedthreadpool (int)

Executor executor = Executors.newFixedThreadPool(n);

Runnable runnable = new Runnable() {
 public void run() {
  // do your thing here
 }
}

executor.execute(runnable);

집행자 프레임 워크를 사용하십시오. 즉 Newfixedthreadpool (N)

  1. 는 경우에 당신의 작업 큐지 않을 것입한 결과 작업을 완료할 수 있습에서 짧은 시간 간격으로 사용할 수 있습니다 Executors.newFixedThreadPool(n);으로 나왔습니다.

    유일한 단점에서 이 솔루션은 무한한 작업 큐 크기입니다.당신을 제어 할 수 없습니다.거대한 더미에서 작업 큐의 성능을 저하시킬 응용 프로그램을 일으킬 수 있습으로 메모리에서 몇 가지 시나리오.

  2. 을 사용하려는 경우 ExecutorServicework stealing 메커니즘 where idle worker threads 공유하는 작업에서 바쁘 worker threads 훔쳐 작업에서 작업합니다.이 반환됩니다 ForkJoinPool 유형의 집행 서비스입니다.

    public static ExecutorService newWorkStealingPool(int 병렬 처리)

    스레드를 생성한 수영장을 유지 관리하는 충분한 스레드를 지원하는 주어진 병렬 처리 수준을 사용할 수 있습 여러 대기열한 경합을 줄.병렬 처리 수준에 해당하는 스레드의 최대 수를 적극적으로 참여하거나,사용,에 종사하는 작업을 처리합니다.실제 쓰레드의 수도 성장하는 동적으로 축소.치 수영장에 대한 보장을하지 않는 순서를 제출하는 작업이 실행됩니다.

  3. 세요 ThreadPoolExecutor 으로 인해 유연한 Api 를 제어하는 많은 paratmeters 제어하는 흐름 작업 실행합니다.

    ThreadPoolExecutor(int corePoolSize, 
                           int maximumPoolSize, 
                           long keepAliveTime, 
                           TimeUnit unit, 
                           BlockingQueue<Runnable> workQueue, 
                           ThreadFactory threadFactory,
                           RejectedExecutionHandler handler)
    

의 경우 모두 설정 corePoolSize and maximumPoolSize as N.여기에 제어할 수 있습니다 작업 큐 크기 자신을 정의 사용자 정의 스레드 공장과 거절 처리 정책이 있습니다.

에서 봐야 관련 SE 질문을 제어하는 수영장 크기를 동적으로:

동적 Thread Pool

직접 굴려면 :

private static final int MAX_WORKERS = n;
private List<Worker> workers = new ArrayList<Worker>(MAX_WORKERS);

private boolean roomLeft() {
    synchronized (workers) {
        return (workers.size() < MAX_WORKERS);
    }
}

private void addWorker() {
    synchronized (workers) {
        workers.add(new Worker(this));
    }
}

public void removeWorker(Worker worker) {
    synchronized (workers) {
        workers.remove(worker);
    }
}

public Example() {
    while (true) {
        if (roomLeft()) {
            addWorker();
        } 
    }
}

근로자가 스레드를 연장하는 수업입니다. 각 작업자는이 클래스의 removeworker 방법을 호출하여 매개 변수로 전달합니다.

그로 인해 집행자 프레임 워크가 훨씬 좋아 보인다.

편집 : 누구든지 이것이 왜 그렇게 나쁜지를 설명하는 대신 왜 그렇게 나쁜지 설명하고 싶습니까?

여기에서 언급했듯이 가장 좋은 방법은 집행자 수업:

그러나 직접 굴려 보려면이 코드를 사용하면 진행 방법을 알 수 있습니다. 기본적으로 모든 새 스레드를 스레드 그룹에 추가하고 그룹에 N 활성 스레드 이상이 없는지 확인하십시오.

Task[] tasks = getTasks(); // array of tasks to complete
ThreadGroup group = new ThreadGroup();
int i=0;
while( i<tasks.length || group.activeCount()>0 ) {
    if( group.activeCount()<N && i<tasks.length ) {
        new TaskThread(group, tasks[i]).start();
        i++;
    } else {
        Thread.sleep(100);
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top