SpringおよびJava Threadの例
Springで「threading」を実行する方法を示す3つの例を次に示します。 わかりやすいコードを参照してください。
1. Spring + Java Threadsの例
Thread
を拡張して単純なJavaスレッドを作成し、@Component
を介してSpringのコンテナによって管理されます。 各リクエストが新しいインスタンスを返し、個々のスレッドを実行できるように、Beanスコープは「prototype」である必要があります。
PrintThread.java
package com.example.thread; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component @Scope("prototype") public class PrintThread extends Thread{ @Override public void run() { System.out.println(getName() + " is running"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getName() + " is running"); } }
AppConfig.java
package com.example.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages="com.example.thread") public class AppConfig{ }
App.java
package com.example; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.example.config.AppConfig; import com.example.thread.PrintThread; public class App { public static void main( String[] args ) { ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); PrintThread printThread1 = (PrintThread) ctx.getBean("printThread"); printThread1.setName("Thread 1"); PrintThread printThread2 = (PrintThread) ctx.getBean("printThread"); printThread2.setName("Thread 2"); PrintThread printThread3 = (PrintThread) ctx.getBean("printThread"); printThread3.setName("Thread 3"); PrintThread printThread4 = (PrintThread) ctx.getBean("printThread"); printThread4.setName("Thread 4"); PrintThread printThread5 = (PrintThread) ctx.getBean("printThread"); printThread5.setName("Thread 5"); printThread1.start(); printThread2.start(); printThread3.start(); printThread4.start(); printThread5.start(); } }
出力-順番は毎回異なります、これはスレッドです:)
Thread 3 is running Thread 2 is running Thread 1 is running Thread 5 is running Thread 4 is running Thread 2 is running Thread 4 is running Thread 5 is running Thread 3 is running Thread 1 is running
2. Springスレッドプール+ Spring非管理Beanの例
SpringのThreadPoolTaskExecutor
を使用してスレッドプールを作成します。 実行中のスレッドは、Springコンテナによって管理される必要はありません。
PrintThread.java – This thread is not managed by Spring, NO @Component
package com.example.thread; public class PrintTask implements Runnable{ String name; public PrintTask(String name){ this.name = name; } @Override public void run() { System.out.println(name + " is running"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + " is running"); } }
Spring-Config.xml – ThreadPoolTaskExecutor in XML file
App.java
package com.example; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import com.example.thread.PrintTask; public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Spring-Config.xml"); ThreadPoolTaskExecutor taskExecutor = (ThreadPoolTaskExecutor) context.getBean("taskExecutor"); taskExecutor.execute(new PrintTask("Thread 1")); taskExecutor.execute(new PrintTask("Thread 2")); taskExecutor.execute(new PrintTask("Thread 3")); taskExecutor.execute(new PrintTask("Thread 4")); taskExecutor.execute(new PrintTask("Thread 5")); //check active thread, if zero then shut down the thread pool for (;;) { int count = taskExecutor.getActiveCount(); System.out.println("Active Threads : " + count); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if (count == 0) { taskExecutor.shutdown(); break; } } } }
出力-順序は毎回異なります。
Thread 1 is running Thread 2 is running Thread 3 is running Thread 4 is running Active Threads : 4 Thread 5 is running Active Threads : 5 Active Threads : 5 Active Threads : 5 Active Threads : 5 Thread 2 is running Thread 1 is running Thread 3 is running Thread 4 is running Thread 5 is running Active Threads : 0
3. Spring Thread Pool + SpringマネージドBeanの例
この例では、ThreadPoolTaskExecutor
を再度使用しており、スレッドを@Component
を介してSpringマネージドBeanとして宣言しています。
以下のPrintTask2
はSpring管理のBeanであり、必要なBeanを簡単に@Autowired
できます。
PrintTask2.java
package com.example.thread; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component @Scope("prototype") public class PrintTask2 implements Runnable{ String name; public void setName(String name){ this.name = name; } @Override public void run() { System.out.println(name + " is running"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + " is running"); } }
AppConfig.java – ThreadPoolTaskExecutor in Spring configuration file
package com.example.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @Configuration @ComponentScan(basePackages = "com.example.thread") public class AppConfig { @Bean public ThreadPoolTaskExecutor taskExecutor() { ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor(); pool.setCorePoolSize(5); pool.setMaxPoolSize(10); pool.setWaitForTasksToCompleteOnShutdown(true); return pool; } }
App.java
package com.example; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import com.example.config.AppConfig; import com.example.thread.PrintTask2; public class App { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); ThreadPoolTaskExecutor taskExecutor = (ThreadPoolTaskExecutor) context.getBean("taskExecutor"); PrintTask2 printTask1 = (PrintTask2) context.getBean("printTask2"); printTask1.setName("Thread 1"); taskExecutor.execute(printTask1); PrintTask2 printTask2 = (PrintTask2) context.getBean("printTask2"); printTask2.setName("Thread 2"); taskExecutor.execute(printTask2); PrintTask2 printTask3 = (PrintTask2) context.getBean("printTask2"); printTask3.setName("Thread 3"); taskExecutor.execute(printTask3); for (;;) { int count = taskExecutor.getActiveCount(); System.out.println("Active Threads : " + count); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if (count == 0) { taskExecutor.shutdown(); break; } } } }
出力-順序は毎回異なります。
Thread 1 is running Thread 2 is running Thread 3 is running Active Threads : 2 Active Threads : 3 Active Threads : 3 Active Threads : 3 Active Threads : 3 Thread 1 is running Thread 3 is running Thread 2 is running Active Threads : 0
上記のプログラムを改善するためにあなたのコメントが大好きです。
ソースコードをダウンロード
ダウンロード–Spring-Thread-Example.zip(22 KB)