| By Parameswaran Seshan | Article Rating: |
|
| October 16, 2008 08:00 PM EDT | Reads: |
5,056 |
As is shown in the process object code above, to acquire a permit to use the critical section, the thread needs to call the Semaphore's acquire() method and after completing the execution of the critical section code, it must release it by calling the release() method on the Semaphore object. Notice that the release() is done in "finally" block. This is to ensure that irrespective of a successful execution of the critical section code or not (an exception happening in it), the Semaphore is released. Otherwise, other threads waiting to access it would end up in indefinite wait.
Receive Activity and Correlation
There could be system activities in the process that are expected to receive invocations into them from outside; they are called "receive activities." In the case of receive activities (and user activities too), the incoming message would contain input parameters for the activity from the caller and these parameters are supplied to the activity directly. Any output parameters from the receive activity is passed back in return to the caller directly also during this time of exchange. Once this is done, the execution of the process then proceeds separately in its own thread and the caller's execution proceeds separately in the caller thread.
In BPML, an activity that is defined with a child element <input> followed by an optional <output> is considered a receive activity. Input and output elements define the input and output parameters for the activity. This means that this type of an activity receives invocation into it, i.e., the activity responds to an input message. Hence when process execution control reaches this activity, the process has to wait for an external party to invoke this action. Once the invocation (or message) is received from the outside, the activity execution proceeds and reaches the next activity in the process flow. The equivalent for this in WS-BPEL is "receive". In the case of the other type of activity, i.e., where we have <output> followed by <input>, the BPMS server invokes the action corresponding to the activity and so no waiting is involved. Once the process instance pauses for the message to arrive, it gets hibernated/passivated after a configured waiting time similar to user activity.
An important concept in receive activity is correlation. This refers to the method of mapping the incoming message to the receive activity of the right process instance among the set of running process instances. For example, let's take an order process that has a confirmation activity (a receive activity) in which the customer has to send a confirmation message to this activity to indicate order confirmation so the order process can proceed. Here, there would be as many order process instances running in the BPMS server as there are orders being processed at a time. The incoming message would have to specify a business attribute and its value to identify which order the message is intended for. In this case, the order ID, which is a unique identifier for each order, could be used as the correlation parameter. The incoming message to the confirmation activity would come with the order ID value for the order it wants to confirm.
In cases where the receive action does not have any output parameters to return to the caller (i.e., asynchronous invocation into the receive activity) or it has output parameters to return to the caller but does not have any activities to perform within it before returning the output parameters, we can implement the receive activity by using the class Exchanger from the concurrent library.
Exchanger is a synchronization point at which two threads can pair and swap elements within pairs. However, unlike a CyclicBarrier, no common task (to be executed before each of these threads continues executing) can be performed. In the ReceiveActivity class, we create an instance of the Exchanger class. Then we call the exchange() method on it, supplying the prepared output parameters in the name-value form as a HashMap object to make this thread wait for the input message to arrive. If there are no output parameters for this activity, then null is supplied. The incoming message thread (the caller thread) would join this Exchanger by calling the exchange() method and passing the input parameters (as a name-value HashMap object) to it as the argument. The exchanger then passes this input parameter HashMap to the ReceiveActivity thread and in turn passes the output parameter HashMap supplied by the ReceiveActivity to the incoming message thread. If there are no output parameters to be returned, null is returned to the incoming message thread. After this, both the threads depart and proceed independently with their executions. The ReceiveActivity's thread (the process execution thread) now completes the ReceiveActivity execution (post-execute) and then moves on to the next activity in the process's sequence.
In Listing 4, before putting the entry in the correlation table, we have to make it thread-safe since parallel threads could be trying to update its entries at the same time. We use a Semaphore class here (with argument 1 and true). The acquire() method on this Semaphore is called before the correlation table entry is made and the release() method on it is called after it but before the activity threads start waiting (via the exchange() method call) for the incoming message. The invoker (i.e., the incoming message to this activity) would do the following (see Listing 5).
If the receive activity has activities within it to be performed before returning the output parameters, we can implement the receive activity by using the class CyclicBarrier (of size two parties) instead of the Exchanger, since we would need to execute a common task (to be executed before each of these threads departs) at the time when the incoming message thread joins with the receive activity's thread. This common task (which extends the Java.lang.Runnable) will execute all the activities defined under (i.e., within) this receive activity in the order in which they are defined. Both the threads, the receive activity thread and the incoming message thread, are held by the CyclicBarrier until the common task's execution is completed. At the end of common task's execution, the two threads depart and move on with their respective executions independently. The code to use the CyclicBarrier here would be similar to what we saw in above for the stateBarrier.
Conclusion
This article showed how we could use the concurrent utility that is now part of Java 5.0 to build multithreaded execution capabilities in a Java application. We saw how a BPMS runtime platform uses this utility library as its core to handle multithreaded execution and synchronization of business processes and realize a high degree of parallelization with accompanying performance benefits.
Resources
- Overview of package util.concurrent Release 1.3.4
- Backport for util.concurrent
- Concurrent Programming in Java - Principles
- API doc
- Stevens, Tim. “Using the New Concurrent Utility Classes in Java 5.0”
- Concurrent collections
- Li Wenlong, Meng Ran, Wang Tao and C. Dulong. Performance Analysis of Java Concurrent Programming: A Case Study of a Video Mining System
- WS-BPEL specification
- The BPML 1.0 specification
Published October 16, 2008 Reads 5,056
Copyright © 2008 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Parameswaran Seshan
Parameswaran Seshan is a Senior architect with E-Comm Research Lab, Infosys Technologies Limited, Bangalore, India. He has around 14 years of work experience in the IT industry, involving research, teaching, architecture, and programming. His areas of interest include Process-centric architecture, Intelligent software systems, software architecture, Business Process Management systems, Web services and Java.
- Why SOA Needs Cloud Computing - Part 1
- Cloud Expo and The End of Tech Recession
- The Transition to Cloud Computing: What Does It Mean For You?
- A Rules Engine Built in PowerBuilder
- Sybase Named “Silver Sponsor” of iPhone Developer Summit
- How PowerBuilder Got Its Groove Back
- The Cloud Has Cross-Border Ambitions
- Ulitzer Names The World's 30 Most Influential Virtualization Bloggers
- Ulitzer Named "New Media" Partner of Greatly Anticipated iStrategy Event in Berlin
- Risks and Enterprise Mobility?
- Steps for Success in Enterprise Mobility?
- Are Mobile Luddites Resisting Mobility?
- The Difference Between Web Hosting and Cloud Computing
- Sybase CTO to Speak at 4th International Cloud Computing Expo
- Why SOA Needs Cloud Computing - Part 1
- Cloud Expo and The End of Tech Recession
- The Transition to Cloud Computing: What Does It Mean For You?
- Five Reasons to Choose a Private Cloud
- Seeding The Cloud: The Future of Data Management
- The Threat Behind the Firewall
- Economy Drives Adoption of Virtual Lab Technology
- Tips for Efficient PaaS Application Design
- A Rules Engine Built in PowerBuilder
- Sybase Named “Silver Sponsor” of iPhone Developer Summit
- Where Are RIA Technologies Headed in 2008?
- PowerBuilder History - How Did It Evolve?
- The Top 250 Players in the Cloud Computing Ecosystem
- Custom Common Dialogs Using SetWindowsHookEx
- DDDW Tips and Tricks
- OLE - Extending the Capabilities of PowerBuilder
- DataWindow.NET How To: Data Entry Form
- Book Excerpt: Sybase Adaptive Server Anywhere
- Sybase ASE 12.5 Performance and Tuning
- Working with SOA & Web Services in PowerBuilder
- Office 2003 Toolbar: A New Look For Your Old PowerBuilder App
- Dynamically Creating DataWindow Objects































