Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

how to execute code asynchronously: a new thread vs JMS?  RSS feed

 
Walter Andresen
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I need to implement asynchronous processing in the web application. When a user logs in, I need to do some time consuming actions, sync it with another system, save some audit
info, etc, etc.

What I can do is to create a separate thread and execute some code, without waiting for a response. Or I can also use JMS.

So, I think I have 3 options:
1. use Java Executor framework and spawn a new thread
2. use Work Manage since this is weblogic app and schedules work for execution on a container-managed thread
3. use JMS, e.g. send a message to a queue and implement a listener that will execute the code asynchronously.

Any recommendation which approach is better and why?
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Walter Andresen wrote:I need to implement asynchronous processing in the web application. When a user logs in, I need to do some time consuming actions, sync it with another system, save some audit
info, etc, etc.
What I can do is to create a separate thread and execute some code, without waiting for a response. Or I can also use JMS.

Why not both?

If all this other stuff is truly asynchronous, then I'd be tempted to simply spawn a Thread, since THAT is the way that Java does things. Now whether that Thread runs JMS or an Executor or WorkManage is entirely up to you, and I'm not enough of an expert to advise you.

I suspect it'll depend entirely on how much interaction there is (or you want) between your Web app and the thing you just started. But "asynchronous" to me says: Thread.

HIH

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 6980
110
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston, I strongly disagree.

You should always try to avoid spawning threads. An application should have a thread pool somewhere that handles the execution of tasks. For simple applications, you can just use an ExecutorService and pass that to the instances that require it, but most application containers have their own thread pool that you should use instead.

Seeing as this is a WebLogic application, you should definitely go for the Work Managers option.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Winston, I strongly disagree.
You should always try to avoid spawning threads...

Why? I agree that you should generally try to avoid synchronization if you can, but if you have have two unrelated tasks, why wouldn't you use the mechanism provided for you by Java to run them?

Whether you decide to use a ThreadPool or ExecutorService etc, etc, is an implementation decision and, in the interests of "dumb code" and the absence of any other information, if I need to run a truly asynchronous process, I'll create a Runnable to do it; and assume that most of those frameworks will be able to accommodate it if I decide to use them.

I say again: IMO, 'asynchronous' suggests Thread. How you run that Thread is a different question altogether.

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 6980
110
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry, I misread. Yes, of course running a task asynchronously requires it to run in a separate thread. What's important is that your application doesn't handle the creation of such threads if it runs inside an application container, because bad thread management may cause an application to start thrashing. This includes using executor services, because you're bypassing the container's own thread pool.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:What's important is that your application doesn't handle the creation of such threads if it runs inside an application container, because bad thread management may cause an application to start thrashing. This includes using executor services, because you're bypassing the container's own thread pool.

Fair enough. I bow to superior knowledge there.

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 6980
110
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Honestly, I don't have much experience with asynchronous tasks in application containers. I think it was Tim who once warned me not to manually spawn any threads within a JEE application, and that wisdom can be extended to applications in general.

Threads are resources, you should handle them the same way you handle database connections.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Threads are resources, you should handle them the same way you handle database connections.

Hmmm. Not quite sure I agree with that - although I follow the general logic.

Threads may be a resource, but they're a resource that is one of the foundation stones of a multi-tasking OS. Therefore, I think it's it's reasonable to assume:
a. They can be created fairly quickly.
b. You can create quite a few of them.
and it's also perfectly possible that the JVM can decide whether to execute a particular "job" as an LWP (at least on Unix/Linux) - which are faster still - or not. Whether it actually does or not, I have no idea; but again, I think it's reasonable to assume that the JVM will do what it "thinks best".

Database connections - particularly over a network link - are an entirely different matter. For starters:
  • They are much "heavier duty".
  • Control of them is at a further remove from your code.
  • They will likely involve added complexities like timeouts - which themselves may be part of the "scheduling" system.

  • And finally, they are usually measured in scores, not thousands.

    So, while it's good to keep in mind that processes are resources, I don't think you have to be anywhere near as frugal about them as with database connections.

    Winston
     
    Junilu Lacar
    Sheriff
    Posts: 10879
    158
    Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Threads aren't as lightweight as you seem to think. https://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html

    I think the similarity between threads and database connections that was alluded to was that both are best managed in pools: thread pools and database connection pools.

    I'm not sure why the JMS option hasn't been discussed. When responsiveness and resource usage is a primary consideration, offloading a resource-intensive or time-consuming job to other processes on an entirely different machine is certainly as good a choice as any. I often do this with background jobs that my applications need to run. This is particularly well suited in a virtualized/cloud environment where server resources can be spun up and down based on demand. JMS is one inter-process communication option. Another is web services. I have implemented both and they worked out well for me.

    An added bonus to this is that it sets you on a path that can lead to an evolution into a microservices architecture.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!