2016-10-06 13 views
3

私は、Trade Automationサイト用のSpring 4 Rest APIを構築しています。Spring 4 TaskSchedulerのパフォーマンスの問題

は、サービス層でcronジョブを動的スプリングTaskScheduler.schedule(Runnab‌​le arg0, Date arg1)を正確に一度、パラメータとして与えられた時に実行されるように、Runnableを作成するインタフェースを使用して作成されます。このスレッドは、私のHibernate DAOレイヤーにアクセスするための別のサービスを呼び出し、将来何かを行います。

構成クラスと実装を以下に示します。

@Configuration 
@EnableWebMvc 
@EnableScheduling 
@ComponentScan("com.example")  
public class SpringMvcConfig extends WebMvcConfigurerAdapter {  
    @Bean 
    public ThreadPoolTaskScheduler taskScheduler() { 
     return new ThreadPoolTaskScheduler(); 
    }  
} 


@Service 
public class TransactionServiceImp implements TransactionService { 

    @Autowired 
    private TaskScheduler scheduler; //org.springframework.scheduling.TaskScheduler; 
    @Autowired 
    private TaskExecutorService taskService; //My service 

    @Transactional 
    public myFunction(){ 

     //some code 

     final Long key = //some id value from db 
     Date exeTime = //some java.util.Date in future 

     Runnable runnable = new Runnable() {    

      private long id = key; 
      public void run() { 
       taskService.doSomething(id); 
      } 
     }; 
     ScheduledFuture<?> sheduler = scheduler.schedule(runnable, exeTime); 

     //some code  
    }  
} 

このコードは正常に動作し、正確な時刻にタスクを実行し、正確に一度されます。日食のデバッグ、によって

その新しいデーモンスレッドは、(httpリクエストを処理する際に、MVC春に)呼ばれるたびscheduler.schedule()を作成していることがわかりました。私の問題は

  1. は、JVMが(むしろ指定 日時にスレッドを作成するよりも)各 scheduler.schedule()コールに新しいデーモンスレッドを作成するというのが私の考えが正しいです、ありますか?

  2. 作成デーモンスレッドはまだタスクが実行された後も EclipseのデバッグにRunning状態を示しています。スレッドは終了すると が破壊されたかどうかは確認されませんrun()メソッド?

  3. それ以外の場合は、パフォーマンスの問題ですか?

+0

使用TaskScheduler' 'これに依存して増加しません。また、代替案を検討したいかもしれません。タスクがスケジュールされていて、JVMがクラッシュしたときにタスクが無くなっても、それが問題でない場合は問題ありません。そうでなければ、石英のようなものを見たいかもしれません。 –

+0

私は 'org.springframework.scheduling.TaskScheduler'インタフェースと' org.springframework.scheduling.concurrent.ThreadPoolTask​​Scheduler'実装を使用しています。トランザクションステータスがdbに格納され、次の起動時にチェックされるため、JVMのクラッシュとタスクは問題になりません。 –

答えて

1

ScheduledThreadPoolExecutor周りThreadPoolTask​​Schedulerラッパー(下地JDK実装)、スレッドは、ワーカースレッドの所定のセットから再利用することができます。各タスクは、作業キューに割り当てられ/処理されます。

でもコアスレッドが最初に作成され、新しい タスクが到着したときにのみ開始され

は、私の考えではなくでスレッドを作成するよりも(そのJVMは、各scheduler.schedule()の呼び出しで新しいデーモンスレッドを作成し、正しいです指定された日時)?

実行時にスレッドインスタンス(Runnable)が作成されるたびに、実行可能であるため、タスクが実行されるか、アイドル状態のキュー内の既存のワーカースレッドが実行されます。プールの最大サイズに達すると、タスクは待機します。

作成されたデーモンスレッドは、タスクの実行後もEclipseデバッグ中のステータスの実行を示しています。 run()メソッドの終了時にスレッドが破棄されるかどうか

のJavaドキュメントがこれを言うスケジューラがシャットダウンするか返さ ScheduledFutureがキャンセルされますと、

実行が終了します。

それ以外の場合はパフォーマンスの問題ですか?実行できるスレッドの最大数は、CPUコアによって制限されます。だから、増加プールのサイズは、必ずしもパフォーマンス

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html

+0

お返事ありがとうございます。さらにデバッグすると、Daemonスレッドを 'TaskScheduler'スレッドとして誤解していたことがわかりました。しかし、彼らはそうではありません。それらはリクエストごとに作成されます(明らかにサーブレットの場合)。 'TaskScheduler'のスレッドは、最初の呼び出しの後も実行を続けます。この単一のスレッドは、後で追加されるすべてのタスクを管理します。だから私は**上記のコードではパフォーマンス上の問題はないと思う**、そうですか? –

+0

はいそれはありません。そして、もしあなたがプールサイズを指定しなかったら、それは1と仮定しました。 – kuhajeyan

関連する問題