Tasks submitted to Fixed threadpool ExecutorService are threadsafe? - java

The tasks submitted uses resource beans from a spring container. Are the methods in the beans thread safe when accessed by concurrent threads of a executor service?

They aren't thread-safe by definition. If your Spring beans are immutable, stateless or properly synchronized (99% of the cases) they are thread safe. Here are few examples of thread-safe Spring beans:
Only final fields:
public class ImmutableService {
private final Dependency dep;
#Autowired
public StatelessService(Dependency dep) {
this.dep = dep;
}
public Foo foo() {
return dep.foo();
}
}
Field is modified only during creation, effectively final:
public class EffectivelyImmutableService {
#Autowired
private final Dependency dep;
public Foo foo() {
return dep.foo();
}
}
No state, typical utility class:
public class StatelessService {
public Foo foo() {
return new Foo();
}
}
Non-atomic operations are synchronized:
public class SynchronizedService {
private int counter;
public synchronized Foo foo() {
return new Foo(counter++);
}
}
AtomicInteger to avoid explicit synchronization (field is final, but the object isn't):
public class AtomicService {
private final AtomicInteger counter = new AtomicInteger();
public Foo foo() {
return new Foo(counter.incrementAndGet());
}
}
Note that this rule applies to all use-cases, not only to tasks using Spring beans in thread pool. For instance if your servlets/controllers use Spring beans, they have to be thread safe as well.

If you were to manually start two threads accessing these beans, would the access be threadsafe then? An executor service does no magic and does not change anything about the code running in its threads. If accessing the beans is not threadsafe from two manually started threads, it's not threadsafe when the code is executed by threads managed by an Executor either.

Related

How to call multiple functions of different Spring beans in async

I am new to Async in Spring boot.
I have a bean A as follows:
class A {
private final B b;
private final C c;
...
int x = b.f();
c.g(x);
...
}
Here I would like to call both f() and g() in async. I have got some ideas from different articles regarding how to make #Async work. But, being a newbie, I cannot understand how would I call g() with the return value of f() in async.
It's pretty straight forward ,Add #EnableAsync annotation to a configuration class or to the main application class then add the #Async annotation to the method that you want to be executed asynchronously on a separate thread. Springboot will setup a thread pool and using proxy will automatically start a new thread to handle the method call. But if you want to return something from the method then use Future. You can also control which thread pool to use by creating a thread pool executor bean like below and specifying it in the #Async annotation.
#Configuration
#EnableAsync
class GeneralConfiguration {
#Bean(name = "asyncTaskExecutor")
public Executor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(10);
threadPoolTaskExecutor.setMaxPoolSize(20);
threadPoolTaskExecutor.setThreadNamePrefix("ScheduledTaskThread-");
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}
class B {
#Async("asyncTaskExecutor") //ask spring to use your thread pool for this async task.
public Future<Integer> f() {
//Do something
return new AsyncResult<Integer>(1);
}
}
class C {
#Async
public void g() {
//Do something
}
}
From your comments, in order to wait for thee result of method f of class B to be provided as input to the method g of class C then use CompletableFuture like :
class B {
#Async("asyncTaskExecutor") //ask spring to use your thread pool for this async task.
public CompletableFuture<Integer> f() {
//Do something
return CompletableFuture.completedFuture(1);
}
}
Then after while calling the method do something like :
...
CompletableFuture<Integer> result = b.f();
CompletableFuture.allOf(result).join(); //add other futures if you want to wait for other calls to complete.
c.g(result.get());
...
Obviously there are other optimized way to use Completable Future . But it depends on how you want to use this in your code. I suggest going through the completable future docs and finding out which suits your use case best.

What are the tricks to make lazy initialization thread safe and efficiency considering the costs of sychronized keyword?

After reading the lazy initialization of expensive resources in the book around Page 106-108 - functional programming in Java by Venkat Subramaniam, it is found hard to understand the tricks with this code snippet
my understandings:
variable heavy in class Holder is of type Supplier<Heavy>
vs
local class HeavyFactory inside the method createAndCacheHeavy is a sub class extends Supplier
It seems only run once to execute that lambda method and then alter the outer member variable of class Holder.heavy
I am confused about below code the heavy is then later assigned with new reference pointing to the sub class extends Supplier
please if anyone could share hints the tricks here to gain the advantages of author proposed to save performance penalty from synchronized keyword and also taking care of thread safety. It also mentioned virtual proxy pattern. Did I miss out any key info to understand it?
package fpij;
import java.util.function.Supplier;
public class Holder {
//only run once here? before heavy get reassigned to HeavyFactory, the local class to that lambda method?
private Supplier<Heavy> heavy = () -> createAndCacheHeavy();
public Holder() {
System.out.println("Holder created");
}
public Heavy getHeavy() {
//the 2nd time it will call always the HeavyFactory.heavyInstance?
return heavy.get();
}
private synchronized Heavy createAndCacheHeavy() {
//create a local class inside method? Is the real trick/hack here I missed out so it will avoid 2nd time the synchronized penalty?
class HeavyFactory implements Supplier<Heavy> {
private final Heavy heavyInstance = new Heavy();
public Heavy get() { return heavyInstance; }
}
if(!HeavyFactory.class.isInstance(heavy)) {
heavy = new HeavyFactory();
}
return heavy.get();
}
public static void main(final String[] args) {
final Holder holder = new Holder();
System.out.println("deferring heavy creation...");
System.out.println(holder.getHeavy());
System.out.println(holder.getHeavy());
}
}
package fpij;
public class Heavy {
public Heavy() { System.out.println("Heavy created"); }
public String toString() { return "quite heavy"; }
}
If you are really concerned on the cost of synchronized, there a simple way to make it work correctly while keeping the initialization lazy.
It use the property that the classloader ensure synchronization when the class is loaded. It garentee that no other thread will be able to access the class until it is fully loaded. And the class load is actually lazy: it load the class only when the class is actually used from the first time.
If the only feature of class HeavyFactory is to provide the singleton instance, it will be loaded only when the getInstance is called and all will play nicely.
class HeavyFactory {
private static final Heavy heavyInstance = initInstance();
public static Heavy getHeavyInstance() {
return heavyInstance;
}
private static Heavy initInstance() {
heavyInstance = new HeavyInstance();
[...] // Other init stuff
return heavyInstance;
}
}
Edit: The init of complex objects and wiring of dependencies is so common that frameworks like JEE or Spring have implemented ways to do simplify it.
If you use spring for example, you would be able to just declare a given service as a singleton and then declare a dependency on it where you need it. The init would be done when the spring framework initialize in proper order:
// We instruct spring to create a shared instance of heavy
// with #Component annotation
// The instance would be created eagerly at the start of the app.
#Component
public class Heavy {
public Heavy() { System.out.println("Heavy created"); }
public String toString() { return "quite heavy"; }
}
// For the example another service using the Heavy shared instance
#Component
public class ClientDependingOnHeavy {
// We ask spring to fill it automatically the shared instance for us.
#Autowired
private Heavy heavy;
public String foo() {
//So we can use the instance like any object.
System.out.println(heavy.toString());
}
}
Well spring or JEE are quite complex advanced frameworks. For a single case they would not be worth it at all. For a whole application it would make sense. You'd need quite some reading/tutorials to make the second example work if you don't already know them. But in the long run, it may be worth the effort.

Performance: Utility class vs. CDI bean

I want to externalize commonly used applicationlogic into a "utility class" called Helper. The applicationlogic needs other CDI beans to work.
Two possibilities:
a)
#SessionScoped
class ControllerWithCdiBean {
#Inject
Helper helper;
public void doIt() {
Object result = helpder.calculate();
}
}
#RequestScoped
class Helper{
#Inject
Service anyService;
public Object calculate() {
return anyService.calc();
}
}
b)
#SessionScoped
class ControllerWithStaticCallsViaDeltaspike {
public void doIt() {
Object result = Helpder.calculate();
}
}
class Helper{
private static Service anyService = BeanProvider.getContextualReference(Service.class);
public static Object calculate() {
return anyService.calc();
}
What about performance? Are there any notable differences? Both solutions are possible for me, is one solutions better than the other?
One disadvantage:
Helpder gets initialized for every Request.
Mark your Helper class as #ApplicationScoped. With this, you will have a single instance per application context.
Still, if it's just an utility class, it shouldn't be a managed bean at all. I would instead mark it as final, define a private constructor and mark all the methods as static. This is because since it's an utility class, it doesn't need to maintain any state.

Handling private write methods on singleton EJBs

I have a singleton EJB whose business methods are all #Lock(READ). However, on special ocassions, some of them call a private method that persists stuff on a database. What's the best way to handle this situation? Should I:
Use #Lock(WRITE) for that private method even though it's not a business method? If so, is this a reliable behaviour?
Do the synchronization on the private method myself? If so, is it safe to synchronize over the EntityManager?
Do something completely different?
This only partially answers your question, but here goes.
You could put the private methods in a "private" businness interface and call them via the container like this:
TestEJB.java:
#Stateless
public class TestEJB implements PrivateIface, PublicIface {
SessionContext ctx;
public void doBusiness() {
PrivateIface businessObject = ctx.getBusinessObject(PrivateIface.class);
businessObject.doPrivateBusinness();
}
#SomeContainerAnnotation
public void doPrivateBusinness() {
}
}
#Local
interface PrivateIface {
void doPrivateBusinness();
}
PublicIface.java:
#Local
public interface PublicIface {
void doBusiness();
}

Spring and Multithreading

I need to start a variable number of threads which in turn each start a varying number of threads (i.e. i threads where the Ith thread needs to start Ki threads) in a spring application.
assuming each of the "I threads" contains an inner class which is autowired how will I generate those instances?
So I have an A bean which needs to somehow generate I instances of a bean which needs to be spring managed to satisfy its dependencies.
I've written a short sample code of what I think is the base for my solution and I've marked the code I'm not sure how to write by ???:
#Component
public class MasterOrchestrator {
public void do(List<DataObjWrapper> list){
ExecutorService es = Executors.newFixedThreadPool(list.size());
for (DataObjWrapper dataObjWrapper : list){
es.submit(???);
}
}
}
#Component
public class ThreadWorkerI implements Runnable{
private int numThreadsForMessageType;
private int numRunsForMessageType;
private DataObj dataObj;
public ThreadWorkerI(int numThreadsForMessageType, int numRunsForMessageType, DataObj dataObj){
this.numThreadsForMessageType = numThreadsForMessageType;
this.numRunsForMessageType = numRunsForMessageType;
this.dataObj = dataObj;
}
#Autowired
private JmsTemplate jmsTemplate;
public void run(){
ExecutorService es = Executors.newFixedThreadPool(numThreadsForMessageType);
for (int i=0;i<numRunsForMessageType;i++){
es.submit(new ActualWorker(i));
}
}
private class ActualWorker implements Runnable{
private int numRun;
private ActualWorker(int numRun){
this.numRun = numRun;
}
public void run(){
//send message using the jmsTemplate the dataObj and numRun
}
}
}
DatObjWrapper contains amongst other members the numThreadsForMessageType, numRunsForMessageType and dataObj.
You can use #Configurable annotation to let Spring inject dependencies into your workers - even the one's that are not managed explicitly by the Spring container.
Instead of starting your own threads it is better to use thread pool or Spring's task executor abstraction. Then your tasks can be Spring beans or manually instantiated.
How about passing a reference to the MasterOrchestrator or the ThreadWorker into the Runnable's constructor? Then you can put all the configuration into the #Component class.
For example:
private class ActualWorker implements Runnable{
private int numRun;
private ActualWorker(ThreadWorkerI owner, int numRun){
this.numRun = numRun;
}
public void run(){
//send message using owner.jmsTemplate, owner.dataObj and numRun
}
}

Categories

Resources