Spring and Java Thread example
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.
package com.mkyong.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");
}
}
package com.mkyong.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages="com.mkyong.thread")
public class AppConfig{
}
package com.mkyong;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.mkyong.config.AppConfig;
import com.mkyong.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.
package com.mkyong.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");
}
}
<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>
package com.mkyong;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import com.mkyong.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.
package com.mkyong.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");
}
}
package com.mkyong.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.mkyong.thread")
public class AppConfig {
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
pool.setCorePoolSize(5);
pool.setMaxPoolSize(10);
pool.setWaitForTasksToCompleteOnShutdown(true);
return pool;
}
}
package com.mkyong;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import com.mkyong.config.AppConfig;
import com.mkyong.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.
In your 2nd example if you raise the Spring ClassPathXmlApplicationContext by reading XML configuration file then why do you make note ‘PrintThread.java – This thread is not managed by Spring, NO @Component’. It is a bean and managed by Spring even with no @Component. Other than that great tutorial, thank you
I’m sorry… I was wrong. That is ThreadPoolTaskExecutor serving as managed bean but the tasks implementing Runnable are not, I see now
Hello,
We are trying to develop an application based on Spring that uses Threads but the beans don’t get autowired at those Threads. We have implemented the code following your tutorial but we aren’t able to get the autowired beans automatically injected. Can someone help us? This is a summary of our current code :
– This Servlet is in charge of creating up to 2 Threads :
@Service
public class AppServlet extends HttpServlet{
(…)
grupoThread = new MessageProcessing[Integer.parseInt(NUMBER_OF_THREADS)];
ApplicationContext context = null;
ClassPathXmlApplicationContext context1 = null;
for(int i=0 ; i<Integer.parseInt(NUMBER_OF_THREADS) ; i++){
context1 = new ClassPathXmlApplicationContext("application-context-base.xml");
context = new AnnotationConfigApplicationContext(AppThreadConfig.class);
threadMessageProcessing = (MessageProcessing) context1.getBean("messageProcessing");
threadMessageProcessing.setThreadNumber(i);
grupoThread[i]= threadMessageProcessing;
ThreadPoolTaskExecutor taskExec = (ThreadPoolTaskExecutor)context.getBean("taskExecutor");
taskExec.execute(threadMessageProcessing);
}
– This is the class mentioned in the tutorial :
package com.package.example;
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.package.example")
public class AppThreadConfig {
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
pool.setCorePoolSize(5);
pool.setMaxPoolSize(10);
pool.setWaitForTasksToCompleteOnShutdown(true);
return pool;
}
}
– This is the Runnable class that it isn't able to inject the Autowired beans :
package com.package.example;
@Component
@Scope("prototype")
public class MessageProcessing implements Runnable {
@Autowired
private static MessageBO messageBo;
@Autowired
private static MessageService myMessageService;
@Override
public void run() {
while(!end){
(…)
Integer inserted = insertMessage(…);
(…)
}
}
private static Integer insertMessage(…) {
(…)
// ****************** At this point, messageBo is null ****************
return inserted;
}
Can you help us, please? Do you why the injected beans aren't able to autowire by themselves?
Thanks.
Great example! Might I ask why you extend Thread instead of implementing Runnable?
Thx great example. When using “Spring Thread Pool + Spring managed bean example” one might need to implement factory pattern for task to be inside the spring context. See -> http://stackoverflow.com/questions/29495353/get-new-instance-of-a-spring-bean
Cheers
No words! simply awesome! Thanks for the great tutorial. The prototype bean in the task executor is a deal breaker for me.
what if i want to control each Thread when to start and choose which printTask should start?I mean iwant to make each thread run as desired and if it start a task the next thread must not start.How can i do it?
How to manage transaction inside Thread. I have tried to use taskExecutor but getting the exception in my DAO class “org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread ”
P
Is there any way to stop the particular thread using the ID/Name?
Very nice examples, helped a lot.
I have a question: it all works fine when just reading from de database. When I try to write to it, I get a “no transaction is in progress” exception. Method is public and in another @Service bean (not in the Runnable one), annotated with @Transactional.
Does anybody has faced a similar problem?
GOOD~!~!
Simply desire to say your article is as amazing. The clearness in your post is simply spectacular
and i can assume you’re an expert on this subject. Well with your permission allow me to grab your feed to keep up to date with forthcoming post. Thanks a million and please keep up the rewarding work.
java.lang.NoClassDefFoundError: and
Caused by: java.lang.ClassNotFoundException: and
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
Exception in thread “main”
Kindly provide a solution for this., when i run a java application testcase. I face this issue. Please provide me a solution. Thanks in advance. I see all the necessary jars imported to the workspace and i am using eclipse helios.
Spring Thread Pool + Spring non-managed bean example…..the run() is not calling after taskexecutor.execute method
Hi All,
I have placed few Java Multi threading questions with complete java code. Please take a look one who need – http://www.javadiscover.blogspot.com/search/label/Threads
Thanks
Anand
Thank You . Keep Going!
we can also use the new scope directly which is thread scope :
http://abdennour-insat.blogspot.com/2012/11/spring-bean-thread-scope.html