We have a BatchManager which contains two static int variables successCount and failCount. This BatchManager represents one job run.
Inside the BatchManager class we offload the tasks to separate threads (dedicated BatchTask thread class and spawn few threads). From each of these threads we update the shared variables successCount or failCount of the BatchManager class for each batch thread run.
This works well when there is only single request and then sequential request but fails for the concurrent runs scenario. I was looking for a way to have counts per object instance (BatchManager) which leverages multi-threading internally (BatchTask) and have the BatchTask thread increment the BatchManager static variables.
It sounds like you don't properly synchronize your threads. What are you doing to prevent race conditions occurring when reading or writing to your static variables?
Joined: Nov 29, 2004
Will using synchronize in the above situation help. From what I understand synchronize only protects simultaneous access to static variables from various threads but still threads incepting from different instances will update the shared variables.
What i want is to have shared variables to be updated by threads of specific instance.
I read about AtomicInteger being apt for this situation but not getting related implementation info.
I see that a Job run maintains the number of failed/succeeded tasks. So there's no problem if you make successCount and failCount as Instance variables in BacthManager class. The only concern would be that access/update of these variables by the multiple threads- BatchTask have to be synchronised. That way you can have multiple BatchManager instances, each having a count of its own success or failed.
Just make sure the updation of these variables is Synchronized.
I hope I have understood your requirements. Correct me if its wrong.
Mohit Sinha wrote:
From what I understand synchronize only protects simultaneous access to static variables from various threads but still threads incepting from different instances will update the shared variables.
Static variables are class specific. So you can synchronize them to protect simultaneous access from difference instances. And I hope by Shared variables you mean- Static variables. And as they are shared by multiple instances of the class- Each instance can override the value which can be read by a different instance.
So if a BatchManager tracks number of failed/succeeded tasks for that job and not concerned about other jobs, you can make the successCount or failCount as instance variables.
Stephan van Hulst
Joined: Sep 20, 2010
Yes, you can use AtomicInteger for this purpose. Just call getAndIncrement() on the counter you want to increment when a task is done.
Alternatively, when you use ints, increment them within a synchronized block, using a shared lock as the monitor. Here is an example:
Just to extend what Stephan said - since you are using a Static variable, and you need to synchronize across possibly multiple instance of the class, you should use the class Object itself, not an instance, to synchronize on:
And as Stephan said, you are probably better off using setter methods which are part of the BatchManager class: