フクロウの深夜翻訳:SpringスレッドTaskExector


前言
マルチスレッドではwebアプリケーションが一般的ですが、特に長期的なタスクを開発する必要があります.
Springでは、自分達のスレッドを作成するのではなく、フレームワークで提供されたツールを追加的に注意して使用することができます.
Springは、ExectorsとしてTaskExecutorの抽象を提供している.このインターフェースはjava.util.concurrent.Executorインターフェースと類似している.springには多くの事前に開発されたインターフェースの実装があり、公式文書で詳細に見ることができます.
SpringコンテキストでTaskExectorを構成することにより、Task Exectorの実現をbeanに注入し、Beanでスレッド池にアクセスすることができます.
beanでスレッド池を使う方法は以下の通りです.
package com.gkatzioura.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * Created by gkatzioura on 4/26/17.
 */
@Service
public class AsynchronousService {
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private TaskExecutor taskExecutor;
    public void executeAsynchronously() {
        taskExecutor.execute(new Runnable() {
            @Override
            public void run() {
                //TODO add long running task
            }
        });
    }
}
設定
まず、Springコンテキストにスレッドプールを登録する必要があります.
package com.gkatzioura.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
/**
 * Created by gkatzioura on 4/26/17.
 */
@Configuration
public class ThreadConfig {
    @Bean
    public TaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(4);
        executor.setMaxPoolSize(4);
        executor.setThreadNamePrefix("default_task_executor_thread");
        executor.initialize();
        return executor;
    }
}
ここでは、スレッド池のコアスレッド数、最大スレッド数、およびスレッド池内のスレッド名のプレフィックスが構成されている.
スレッド池の配置が完了すると、次の手順は簡単になります.スプリングのcomponentにスレッド池を注入して、Runnableタスクをスレッド池に提出して完成します.
私たちの非同期コードは、アプリケーションの他のコンポーネントと対話して注入する必要があるかもしれないので、Prottype範囲のRunnableの例を作成するのが良い方法です.(Prottypeは、呼び出しごとに新しいインスタンスを作成します)
package com.gkatzioura;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
 * Created by gkatzioura on 10/18/17.
 */
@Component
@Scope("prototype")
public class MyThread implements Runnable {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyThread.class);
    @Override
    public void run() {
        LOGGER.info("Called from thread");
    }
}
その後、私たちはexectorsをサービスに注入し、それを使って実行可能なインスタンスを実行します.
package com.gkatzioura.service;
import com.gkatzioura.MyThread;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * Created by gkatzioura on 4/26/17.
 */
@Service
public class AsynchronousService {
    @Autowired
    private TaskExecutor taskExecutor;
    @Autowired
    private ApplicationContext applicationContext;
    public void executeAsynchronously() {
        MyThread myThread = applicationContext.getBean(MyThread.class);
        taskExecutor.execute(myThread);
    }
}
Asyncキーワード
springによって提供されたAsyncキーワードを通じて、私達はRunnable類に非同期のタスクをカプセル化する必要もなく、直接に注釈を使えばいいです.
@Async
@Transactional
public void printEmployees() {
 
    List employees = entityManager.createQuery("SELECT e FROM Employee e").getResultList();
    employees.stream().forEach(e->System.out.println(e.getEmail()));
}
このクラスは、プロキシによってデフォルトのスレッドプールに提出されます.
@Async
@Transactional
public CompletableFuture> fetchEmployess() {
    List employees = entityManager.createQuery("SELECT e FROM Employee e").getResultList();
    return CompletableFuture.completedFuture(employees);
}
この方法は非同期実行のFuture結果を返します.
Asyncキーを開くには、構成にEnbaleAsync情報を追加する必要があります.
package com.gkatzioura.config;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 
import java.util.concurrent.Executor;
 
/**
 * Created by gkatzioura on 4/26/17.
 */
@Configuration
@EnableAsync
public class ThreadConfig {
 
    @Bean
    public TaskExecutor threadPoolTaskExecutor() {
 
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(4);
        executor.setMaxPoolSize(4);
        executor.setThreadNamePrefix("sgfgd");
        executor.initialize();
 
        return executor;
    }
 
}
参考文献
spring and async
もっと多くの開発技術を知りたいです.面接教程とインターネット会社の中で推します.不定期で福祉が支給されますよ.