I am doing the chat project in Java with Spring 3.2.
Normally in Java I can create a thread like this:
public class Listener extends Thread{
public void run(){
while(true){
}
}
}
and start the thread by start().
But in Spring 3.x is there any special classes or any special way to achieve the thread functionality?
My requirements:
I have 2 telecom domain servers. In my application I need to initialize the servers to create the protocol.
After the servers are initialized, I need to start two threads to listen the responses from the telecom domain servers.
What I have done was given below:
public class Listener extends Thread{
public void run(){
while(true){
if(ServerOne.protocol != null){
Message events = ServerOne.protocol.receive();
//Others steps to display the message in the view
}
}
}
}
Is it possible to do the java thread functionality with the quartz ?
If possible which one is better ? if no means , what is the reason ?
Hope our stack members will give the better solution.
Spring's TaskExecutor is a good way to run these threads in a managed environment. You could refer to http://static.springsource.org/spring/docs/3.0.x/reference/scheduling.html for some examples.
Java has what you need. I advise against using Thread manually. You should always use something that manages the threads for you. Please have a look at this: https://stackoverflow.com/a/1800583/2542027
You could use Spring's ThreadPoolTaskExecutor
You can define your executor as such in you configuration file
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" destroy- method="shutdown">
<property name="corePoolSize" value="2" />
<property name="maxPoolSize" value="2" />
<property name="queueCapacity" value="10" />
</bean>
<task:annotation-driven executor="taskExecutor" />
In your Listener you could have a method that does all the work in it and annotate this method with the #Async annotation. Ofcourse, Listener should also be Spring managed.
public class Listener{
#Async
public void doSomething(){
while(true){
if(ServerOne.protocol != null){
Message events = ServerOne.protocol.receive();
//Others steps to display the message in the view
}
}
}
}
Now everytime doSomething is called, a new thread will be created if there are less than corePoolSize number of threads being run by the executor. Once corePoolSize number of threads are created, every subsequent call to doSomething will create a new thread only if there are more than corePoolSize but less than maxPoolSize running (not idle) threads and the thread queue is full. More about pool sizes can be read in the java docs
Note : While using #Async you might encounter the following exception if CGLIB library is not made available in your application.
Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
To overcome this without having to add CGLIB dependencies, you can create an interface IListener that has doSomething() in it and then have Listener implement IListener
Since Spring 3, you can use #Schedule annotation:
#Service
public class MyTest {
...
#Scheduled(fixedDelay = 10)
public getCounter() {...}
}
with <context:component-scan base-package="ch/test/mytest"> and <task:annotation-driven/> in the context file
Please refer to this tutorial:http://spring.io/blog/2010/01/05/task-scheduling-simplifications-in-spring-3-0/
Related
The application I am working on receives notifications from external systems, which I want to process sequentially, since I am experiencing some deadlocks.
I am using the TaskExecutor from Spring which is the equivalent of the JDK 1.5's Executor.
I've implemented it in the following way:
I've a java interface containing 1 method:
public interface AsynchronousService {
void executeAsynchronously(Runnable task);
}
and the corresponding implementation:
public class AsynchronousServiceImpl implements AsynchronousService {
private TaskExecutor taskExecutor;
#Override
public void executeAsynchronously(Runnable task) {
taskExecutor.execute(task);
}
#Required
public void setTaskExecutor(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
}
Here is the configuration of the TaskExecutor. I am not sure about this configuration. Since, I want the notifications to execute sequentially, I set 1 for both, corePoolSize and maxPoolSize. This means that only 1 thread will be created in the threadpool and retrieves the notifications sequentially from the queue. I also set "false" for "WaitForTasksToCompleteOnShutdown" in order not to shutdown after each task is executed, but rather when the spring context is destroyed. Am I generally correct with my assumptions?
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="1"/>
<property name="maxPoolSize" value="1"/>
<property name="WaitForTasksToCompleteOnShutdown" value="false"/>
</bean>
Here I execute then the code:
asynchronousService.executeAsynchronously(new Runnable() {
#Override
public void run() {
someMethod.processNotification(notification)
}
});
What do you think of my implementation? Did I miss something?
I am not sure if/where I need to implement some error-handling?
EDIT:
Is there any possibilty to tweak the implementation of the task-executor in spring to use a custom queue? Or how difficult is it to prioritize the tasks in the queue? I looked at some implementations but most of them implement the executor-service from sratch without using Spring.
The application I am working on receives notifications from external
systems, which I want to process sequentially, since I am experiencing
some deadlocks.
If you process sequentially, you don't need thread pool anyway.
Since, I want the notifications to execute sequentially, I set 1 for
both, corePoolSize and maxPoolSize
This will create a fixed pool size of 1. There's only one thread so it will execute sequentially
I also set "false" for "WaitForTasksToCompleteOnShutdown" in order not
to shutdown after each task is executed, but rather when the spring
context is destroyed
This is wrong. This flag tells the pool to wait for task completion on shutdown (Eg. If you call pool.shutdownNow(), the pool will wait for any executing threads)
And to summarize: Don't use thread pool if you want to execute one by one serially without concurrent
I recently learned that I can easily make any session bean method Asynchronous by simply adding the #Asynchronous annotation.
E.g.
#Asynchronous
public Future<String> processPayment(Order order) throws PaymentException {
...
}
I know that Java EE 7 added Concurrency Utilities, but in Java EE 6, where is the thread pool configuration of the #Asyncronous methods? is there a way to set a timeout? is it a fixed thread pool? a cached one? what is it's priority? Is it configurable somewhere in the container?
Even though the solution I found was tested only on Java EE 7/GlassFish 4.1, I think that it should work for GlassFish 3.x too.
There's a JIRA entry on java.net where the different settings are listed. As Oracle is going to pull the plug on that site, I'll quote the relevant post here (formatting added):
The configuration is in domain.xml, for example,
<ejb-container>
<property name="thread-core-pool-size" value="10"></property>
<property name="thread-max-pool-size" value="100"></property>
<property name="thread-queue-capacity" value="20"></property>
<property name="thread-keep-alive-seconds" value="600"</property>
<property name="allow-core-thread-timeout" value="false"></property>
<property name="prestart-all-core-threads" value="false"></property>
</ejb-container>
All of the above properties are optional. Their default values:
thread-core-pool-size: 16
thread-max-pool-size: 32
thread-queue-capacity: Integer.MAX_VALUE
thread-keep-alive-seconds: 60
allow-core-thread-timeout: false
prestart-all-core-threads: false
Via that thread, I also found a blog post that explains how the core and max pool size work. Quote of the important point:
In the past SUN declared correctly: "That is exactly how it is
supposed to behave. First the threads grow to coreSize, then the queue
is used, then if the queue fills up then the number of threads
expands from coreSize to maxSize. Hence if you use an unbounded queue
the last part never happens. This is all described in the
documentation. If you want an unbounded queue but more threads then
increase the core size. Otherwise consider whether a bounded queue is
more suitable to your needs."
I think timeout could be achieved by invoking Future.cancel(boolean) from a method annotated #Timeout. Requires keeping a reference to the Future returned by the async method, Singleton-ejb can be used for this.
#Stateless
public class AsyncEjb {
#Resource
private SessionContext sessionContext;
#Asynchronous
public Future<String> asyncMethod() {
...
//Check if canceled by timer
if(sessionContext.wasCancelCalled()) {
...
}
...
}
}
#Singleton
public class SingletonEjb {
#EJB
AsyncEjb asyncEjb;
Future<String> theFuture;
public void asyncMethod() {
theFuture = asyncEjb.asyncMethod();
//Create programatic timer
long duration = 6000;
Timer timer =
timerService.createSingleActionTimer(duration, new TimerConfig());
}
//Method invoked when timer runs out
#Timeout
public void timeout(Timer timer) {
theFuture.cancel(true);
}
}
Edit (new below):
In glassfish you may configure the ejb-pool by seting below attributes in the admin console
Initial and Minimum Pool Size
Maximum Pool Size
Pool Resize Quantity
Pool Idle Timeout
see Tuning the EJB Pool
I have a remote service that I'm calling to load pricing data for a product, when a specific event occurs. Once loaded, the product pricing is then broadcast for another consumer to process elsewhere.
The calling code doesn't care about the response - it's fire-and-forget, responding to an application event, and triggering a new workflow.
In order to keep the calling code as quick as possible, I'd like to use #Async here, but I'm having mixed results.
The basic flow is:
CallingCode -> ProductPricingGateway -> Aggregator -> BatchedFetchPricingTask
Here's the Async setup:
<task:annotation-driven executor="executor" scheduler="scheduler"/>
<task:scheduler id="scheduler" pool-size="1" />
<task:executor id="executor" keep-alive="30" pool-size="10-20" queue-capacity="500" rejection-policy="CALLER_RUNS" />
The other two components used are a #Gateway, which the intiating code calls, and a down-stream #ServiceActivator, that sits behind an aggregator. (Calls are batched into small groups).
public interface ProductPricingGateway {
#Gateway(requestChannel="product.pricing.outbound.requests")
public void broadcastPricing(ProductIdentifer productIdentifier);
}
// ...elsewhere...
#Component
public class BatchedFetchPricingTask {
#ServiceActivator(inputChannel="product.pricing.outbound.requests.batch")
public void fetchPricing(List<ProductIdentifer> identifiers)
{
// omitted
}
}
And the other relevant intergation config:
<int:gateway service-interface="ProductPricingGateway"
default-request-channel="product.pricing.outbound.requests" />
<int:channel id="product.pricing.outbound.requests" />
<int:channel id="product.pricing.outbound.requests.batch" />
I find that if I declare #Async on the #ServiceActivator method, it works fine.
However, if I declare it on the #Gateway method (which seems like a more appropriate place), the aggregator is never invoked.
Why?
I'm struggling to see how #Async would work anywhere here, because the starting point is when your code calls the ProductPricingGateway.broadcastPricing() method.
With #Async on the gw, what would the scheduler send?
Similarly, with #Async on the service, what would the scheduler pass in in identifiers?
The correct way to go async as soon as possible would be to make product.pricing.outbound.requests an ExecutorChannel...
http://static.springsource.org/spring-integration/reference/html/messaging-channels-section.html#executor-channel
http://static.springsource.org/spring-integration/reference/html/messaging-channels-section.html#channel-configuration-executorchannel
...where the calling thread hands off the message to a task executor.
One of the Spring features I like the most is how you can handle properties loaded from a file. You only to need to set up a bean like the one below
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/app.properties" />
</bean>
Now you are able to inject the properties values loaded from the app.properties into your beans by using either xml (see below) or annotations.
<bean class="com.example.PersonDaoImpl">
<property name="maxResults" value="${results.max}"/>
</bean>
results.max is one of the properties.
I'm great fan of this feature because it enables me to create quite flexible applications that I can turn on/off some functionality by only changing one property - without redeploying the app.
Now I'm working with JBoss Seam and I've been struggling to find a way to do something similar using this framework.
Does anyone know how to do it? If not, does anyone have any idea of how I could handle properties in a nice way using Seam (I have seen some ways - but none of them were good enough).
Thanks.
If there's no appropriate way using you software stack (is there really no dependency injection!?). I'd say: Use Google Guice (https://code.google.com/p/google-guice/ , https://code.google.com/p/google-guice/wiki/Motivation?tm=6)!
Bad thing with Guice: You may have to read a lot to understand how it works, and what you can do with it. But after it's running you will simply inject your Properties object where you need it:
class YourClass {
#Inject Properties myProperties;
#Inject
public YourClass() { ... }
public void someMethod() {
use the property
}
}
or if you need the properties inside the constructor, you could also do:
class YourClass {
final Properties myProperties;
#Inject
public YourClass(Properties myProperties) {
this.myProperties = myProperties;
}
public void someMethod() {
use the property
}
}
Using Guice maybe enforces you to refactor your whole app.
But if you already have some DI framework, you should simply use that :)
i opened this bug in the spring bug tracker. would be cool if some clever people here can already help me
https://jira.springsource.org/browse/SPR-9341
Set "true" on daemon property for the scheduler - eg
<!-- task scheduling for #Scheduled annotation -->
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="1" />
<bean id="myScheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
<property name="poolSize" value="2" />
<property name="threadNamePrefix" value="myScheduler-"/>
<property name="waitForTasksToCompleteOnShutdown" value="false" />
<property name="daemon" value="true" />
</bean>
Have you tried having your #Scheduled bean implement DisposableBean (so it can be informed when the Spring context is shutting down) and explicitly closing the context in your main() method?
Conceptually, I don't see how the code posted can work like you expect. Spring needs to launch new threads to run your #Scheduled task at the time/rate you configure, which means that when the code in your main() method exits, there are non-daemon threads still running in the JVM. If you don't tell Spring to shut these threads down, then how will they be terminated?
edit: to be clear, I think the solution is to explicitly call close() on your ApplicationContext. Otherwise Spring does not have a way to tell the executor service running your scheduled tasks to shut itself down. A JVM shutdown hook will not be invoked when main() exits since non-daemon threads are still running.
This is the solution using Java config
#Bean
public TaskScheduler daemonTaskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setDaemon(false);
taskScheduler.setThreadNamePrefix("daemon");
taskScheduler.setPoolSize(5);
return taskScheduler;
}
or if you want to really get into the details, the config class can be like this
#Configuration
public class SchedulerConfig implements SchedulingConfigurer {
#Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
One thing is not supported though is to be able to use multiple TaskSchedulers within a single application. I opened a JIRA for that