2017-12-24 35 views
0

이 주제를 많이 연구했지만 유용한 정보를 찾을 수 없습니다. 그리고이 플랫폼에 대한 첫 번째 질문을하기로했습니다. 따라서 특정 기간에 작업을 반복하기 위해 예정된 실행 프로그램을 사용하고 있습니다. 모든 것이 좋습니다. 하지만 오해가 있습니다 .... 내 코드는 작업을 실행하지만 작업이 일정 시간보다 오래 걸리면 작업을 마칠 때까지 기다렸다가 나중에 새 작업을 시작합니다. 일정 시간에 도착하면 작업 실행을 원하고 이전 작업을 마칠 때까지 기다리지 마십시오. 이것을 어떻게 할 수 있습니까? 스윙 프로젝트에서 SwingWorker를 사용했지만이 프로젝트는 스윙 프로젝트가 아닙니다. 읽어 주셔서 감사합니다.ScheduledThreadPoolExecutor 동시 작업

Main 메서드

 LogFactory.log(LogFactory.INFO_LEVEL, Config.MODULE_NAME + " - Available processors for Thread Pool: " + AVAILABLE_PROCESSORS); 
    ScheduledExecutorService executor = Executors.newScheduledThreadPool(AVAILABLE_PROCESSORS); 
    LogFactory.log(LogFactory.INFO_LEVEL, Config.MODULE_NAME + " - [ScheduledExecutorService] instance created."); 
    MainWorker task = new MainWorker(); 
    LogFactory.log(LogFactory.INFO_LEVEL, Config.MODULE_NAME + " - [Main worker] created..."); 
    executor.scheduleWithFixedDelay(task, 0, Config.CHECK_INTERVAL, TimeUnit.SECONDS); 

홈페이지 노동자

public class MainWorker implements Runnable { 

private final NIFIncomingController controller = new NIFIncomingController(); 

@Override 
public void run() { 
    LogFactory.log(LogFactory.INFO_LEVEL, Config.MODULE_NAME + " - [Task] executed - [" + Thread.currentThread().getName() + "]"); 
    controller.run(); 
} 

}이 동작은 아치 방법이 없습니다 ScheduledExecutorService.scheduleAtFixedDelay()

/** 
* Creates and executes a periodic action that becomes enabled first 
* after the given initial delay, and subsequently with the 
* given delay between the termination of one execution and the 
* commencement of the next. If any execution of the task 
* encounters an exception, subsequent executions are suppressed. 
* Otherwise, the task will only terminate via cancellation or 
* termination of the executor. 
**/ 

에 대한 자바 독에 설명되어

+0

누군가 당신을 도울 희망이 있다면 코드를 보여줘야합니다. – Alan

+0

죄송합니다. 잊었습니다.) 예제 코드를 제공했습니다. – user8920693

답변

0

이브 동시 실행 ScheduledExecutorService. 쿼츠 스케줄러를 확인해 볼 수는 있지만 타사 라이브러리입니다

+0

그럼 멀티 스레딩이있는 이유는 하나의 작업 만 실행할 수 있습니다. 아니면이 스레드 풀? – user8920693

+0

여러 가지 다른 작업을 예약 할 수 있으며 동시에 여러 작업이 실행됩니다. 마찬가지로 태스크 A는 5 분마다 실행되고 태스크 B는 10 분마다 실행되고 얼마 동안 (크기가 2보다 크거나 같은 스레드 풀이있는 경우) 작업 A와 B가 동시에 실행됩니다. – Ivan

+0

그런 다음 내 코드에서 scheduledThreadPool은 쓸모가 없습니다. 맞습니까? 왜냐하면, 나는 하나의 작업만을 사용하기 때문입니다. – user8920693

0

원하는 동작을 수행하기 위해 여러 실행 프로그램을 결합 할 수 있습니다.

import java.text.DateFormat; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.TimeUnit; 


public class CombinedThreadPoolsExample { 

    private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 
    private static final int INITIAL_DELAY = 0; 
    private static final int FIXED_DELAY_IN_MILLISECONDS = 1000; 
    private static final int TASK_EXECUTION_IN_MILLISECONDS = FIXED_DELAY_IN_MILLISECONDS * 2; 

    public static void main(String[] args) { 
     int availableProcessors = Runtime.getRuntime().availableProcessors(); 
     System.out.println("Available processors: [" + availableProcessors + "]."); 
     ExecutorService fixedThreadPool = Executors.newFixedThreadPool(availableProcessors); 

     Runnable runnableThatTakesMoreTimeThanSpecifiedDelay = new Runnable() { 
      @Override 
      public void run() { 
       System.out.println("Thread name: [" + Thread.currentThread().getName() + "], time: [" + DATE_FORMAT.format(new Date()) + "]."); 
       try { 
        Thread.sleep(TASK_EXECUTION_IN_MILLISECONDS); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }; 

     ScheduledExecutorService singleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor(); 
     singleThreadScheduledExecutor.scheduleWithFixedDelay(new Runnable() { 
      @Override 
      public void run() { 
       fixedThreadPool.execute(runnableThatTakesMoreTimeThanSpecifiedDelay); 
      } 
     }, INITIAL_DELAY, FIXED_DELAY_IN_MILLISECONDS, TimeUnit.MILLISECONDS); 
    } 
} 

출력의 첫 번째 라인

가 내 컴퓨터에 대해 다음과 같습니다 : 작업 실행이 걸릴 수 있습니다 때

Available processors: [8]. 
Thread name: [pool-1-thread-1], time: [2017-12-25 11:22:00.103]. 
Thread name: [pool-1-thread-2], time: [2017-12-25 11:22:01.104]. 
Thread name: [pool-1-thread-3], time: [2017-12-25 11:22:02.105]. 
Thread name: [pool-1-thread-4], time: [2017-12-25 11:22:03.105]. 
Thread name: [pool-1-thread-5], time: [2017-12-25 11:22:04.106]. 
Thread name: [pool-1-thread-6], time: [2017-12-25 11:22:05.107]. 
Thread name: [pool-1-thread-7], time: [2017-12-25 11:22:06.107]. 
Thread name: [pool-1-thread-8], time: [2017-12-25 11:22:07.107]. 
Thread name: [pool-1-thread-1], time: [2017-12-25 11:22:08.108]. 
Thread name: [pool-1-thread-2], time: [2017-12-25 11:22:09.108]. 
Thread name: [pool-1-thread-3], time: [2017-12-25 11:22:10.108]. 
Thread name: [pool-1-thread-4], time: [2017-12-25 11:22:11.109]. 

그러나 이러한 솔루션에 의존주의, 아래 예제 코드를 찾아주세요 오랜 시간, 수영장 크기와 비교하십시오.

private static final int TASK_EXECUTION_IN_MILLISECONDS = FIXED_DELAY_IN_MILLISECONDS * 10; 

이것은 실행하는 동안 예외가 발생하지 않습니다,하지만 실행 사이의 지정된 지연을 적용 할 수 없습니다의 우리가 작업 실행에 필요한 시간을 증가한다고 가정 해 봅시다. 앞서 언급 한 지연 변경 후 실행 결과에서 확인할 수 있습니다.

Available processors: [8]. 
Thread name: [pool-1-thread-1], time: [2017-12-25 11:31:23.258]. 
Thread name: [pool-1-thread-2], time: [2017-12-25 11:31:24.260]. 
Thread name: [pool-1-thread-3], time: [2017-12-25 11:31:25.261]. 
Thread name: [pool-1-thread-4], time: [2017-12-25 11:31:26.262]. 
Thread name: [pool-1-thread-5], time: [2017-12-25 11:31:27.262]. 
Thread name: [pool-1-thread-6], time: [2017-12-25 11:31:28.263]. 
Thread name: [pool-1-thread-7], time: [2017-12-25 11:31:29.264]. 
Thread name: [pool-1-thread-8], time: [2017-12-25 11:31:30.264]. 
Thread name: [pool-1-thread-1], time: [2017-12-25 11:31:33.260]. 
Thread name: [pool-1-thread-2], time: [2017-12-25 11:31:34.261]. 
Thread name: [pool-1-thread-3], time: [2017-12-25 11:31:35.262]. 
0

이는 단일 실행 프로그램을 사용하여 수행 할 수 있습니다. 귀하의 일정 시간이 Y라고 가정하십시오.

  • 최악의 경우에 작업이 취할 수있는 시간을 확인하십시오. Say X
  • 제어 할 수없는 경우 태스크 구현에서 제어하여 시간 초과를 식별하십시오.
  • X> Y, 다음 다른 작업 개체를 생성하고 일정 시간
  • 을 두 배로한다면 코드는
executorService.schedule(taskObject1, 0/*Initial Delay*/, 2Y); 
executorService.schedule(taskObject2, Y/*Initial Delay*/, 2Y); 
  • X의 경우> N처럼 (Y)를 보일 수 있습니다 (n + 1) Y 및 초기 지연을 각각 0, 2Y, 3Y ...... (n-1) Y로하여 n + 1 작업을 생성하십시오.