Reputation: 1499
I might have been doing something really wrong. So, I have Spring's @Async
Let's say I have this piece of code
@Async("poolbeanname")
Function () {
// some code
}
I have one more, let's say I have this piece of code
@Async("poolbeanname")
Function () {
CompletableFuture.runAsync{ new Runnable ()...}
}
Now with the second code I can see, some threads got spawned but the first approach doesn't seem to spawn more than one?
Upvotes: 4
Views: 11952
Reputation: 4691
As @M.Deinum underlined in his comment, doing this:
@Async("poolbeanname")
Function () {
CompletableFuture.runAsync{ new Runnable ()...}
}
Is useless unless you really need it, because: @Async
sends the execution of your method in the poolbeanname
thread pool and CompletableFuture.runAsync{ new Runnable ()...}
will spawn new thread out of your poolbeanname
.
You can simply do this:
@Async("poolbeanname")
Function () {
CompletableFuture.completedFuture( futureResult);
}
Note that because of spring's object proxies, if you do this:
@Service
class YourService {
callAsyncFunction(){
function(); //@Async will not work here
}
@Async("poolbeanname")
function () {
CompletableFuture.completedFuture( futureResult);
}
}
But you can use this workaround by auto-injecting the bean.
@Service
class YourService {
@Autowired
@Lazy
YourService self;
callAsyncFunction(){
self.function(); //@Async will work here
}
@Async("poolbeanname")
function () {
CompletableFuture.completedFuture( futureResult);
}
}
Upvotes: 1
Reputation: 1148
@Async("poolbeanname")
Function () {
}
The above snippet will execute asynchronously using a thread pool, if you have @EnableAsync
in a configuration class.
@Configuration
@EnableAsync
or
@SpringBootApplication
@EnableAsync
When asynchronous is enabled, spring will search for a custom taskExecutor or a executor bean, if it is not found it will default to its own taskExecutor.
Check your log for the line where it says Initializing ExecutorService....
Out of the box it says that it initialized o.s.s.concurrent.ThreadPoolTaskExecutor
which will give you a core pool size of 1 by default.
To override the executor one only has to add a factory method to a configuration class for the Executor
.
@Bean
public Executor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(10);
threadPoolTaskExecutor.setMaxPoolSize(50);
//etc...
return threadPoolTaskExecutor;
}
If the executor was overridden, it might be that a one thread pool size was specified or Executors.newSingleThreadExecutor();
was used.
CompletableFuture:
The code CompletableFuture.runAsync{ new Runnable ()}
will create a CompletableFuture
instance and execute the code asynchronously (create a thread) every time it is called.
CompletableFuture<Void> future
= CompletableFuture.runAsync(() -> "This is processed asynchronously");
Upvotes: 1
Reputation: 58882
To enable using @Async
you should use @EnableAsync
Let’s start by enabling asynchronous processing with Java configuration – by simply adding the @EnableAsync to a configuration class:
@Configuration @EnableAsync public class SpringAsyncConfig { ... }
And you must use a public
method called from other class:
@Async has two limitations:
it must be applied to public methods only
self-invocation – calling the async method from within the same class – won’t work
Upvotes: 5