Here are 3 examples to show you how to do “threading” in Spring. See the code for self-explanatory.
1. Spring + Java Threads example
Create a simple Java thread by extending
Thread
, and managed by Spring’s container via @Component
. The bean scope must be “prototype“, so that each request will return a new instance, to run each individual thread.
PrintThread.java
package com.mitul.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.mitul.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages="com.mitul.thread") public class AppConfig{ }
App.java
package com.mitul; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.mitul.config.AppConfig; import com.mitul.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(); } }
Output – The order will be vary each time, this is thread :)
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 Thread Pool + Spring non-managed bean example
Uses Spring’s
ThreadPoolTaskExecutor
to create a thread pool. The executing thread is not necessary managed by Spring container.
PrintThread.java – This thread is not managed by Spring, NO @Component
package com.mitul.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
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="5" /> <property name="maxPoolSize" value="10" /> <property name="WaitForTasksToCompleteOnShutdown" value="true" /> </bean> </beans>
App.java
package com.mitul; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import com.mitul.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; } } } }
Output – The order will be vary each time.
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 managed bean example
This example is using
ThreadPoolTaskExecutor
again, and declares the thread as Spring managed bean via @Component
.
The below
PrintTask2
is Spring managed bean, you can @Autowired
any required beans easily.
PrintTask2.java
package com.mitul.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.mitul.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.mitul.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.mitul; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import com.mitul.config.AppConfig; import com.mitul.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; } } } }
Output – The order will be vary each time.
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
Love your comment to improve above program.
No comments:
Post a Comment