Suppose I have DAO named Assignment which declare with #Document map with a mongo collection name Assignment.
Then I have a service bean for example AssigmentImpl which is in singleton scope, doing a update operation where it fetch the persisted DAO and update some with the REST input data for Assignment.
#Service
public class AssignmentImpl{
public Assignment updateAssignment(Assignment assignment){
Assignment assignmentExsisting = assignmentRepo.getAssignment(assignment.getId());
BeanUtils.copyProperties(assignment,assignmentExsisting);
assignmentRepo.save(assignmentExsisting);
}
}
Suppose multiple threads (users) doing the update operations to the different assignments.
Being AssignmentService is singleton it will return same copy to different users. How does it reference the Assignment object? If i say, since Assignment object is not singleton, it will return different object reference to AssignmentImpl when each users do update operation, is it right?
In that case user A might get assignment id 123 before do the update operation and when user B start do the update operation AssignmentImpl would change the assignment reference to different assignment id 456. In that case user A would update a totally different assignment. Is that be possible? If so how can we prevent it? Make the update operation synchronized or is there any other good solutions?
No, it won't be the way you are thinking, note that even service class is singlton every call to update won't overlap any other method call's execution as both will be executed in different threads created by server. So, the operation will take place as per the given assignment and two users' result won't get interchanged, why? because each thread executes method independently but the problem will arise when two threads tries to modify sate of shared element i.e. change value of object declared at class level in your service method.
For example, two buses are starting journey from point A to point B. Now, none of the buses have shared passengers (it's not possible right?), both have their own passengers and own fuel however the mechanism (repository and service) for both buses remains same.
You see two threads are not sharing anything here as far as I can tell, yes it uses repository bean but it doesn't modify it's state it will just send assignment to store and id to retrieve assignment.
Related
For example 1 employee class is there contains employee id and employee name,and i created object for this employee class, then here 2 threads are there, these 2 threads want to execute the same employee object, then what problem will occur?
If 1 thread(t1) changes the value of employee id to 1 and another thread(t2) change the value of employee id to 2, then what problem will occur? and how to resolve it?
I checked in internet and i got it as race condition, but didn't understand completely.
Here thread names are t1,t2 and employee class is
public class Employee{
private int employeeid;
private string empname;
}
employee object creation:
Employee employee = new Employee()
if 1 thread(t1) changes the value of employee id to 1 and another thread(t2) change the value of employee id to 2, then what problem will occur?
That scenario is called a data race. If two threads each set the same variable to one value or another, then the end result will be that the variable holds one value or the other. It is not actually possible for two threads to store to the same location at the same time: The memory system will serialize the stores. So, the outcome depends on which one went first and which one went second.
There's no practical way to predict which one will go first and which will go second, so that means there's no practical way to predict the outcome. In most programs, that's considered to be a Bad Thing.
and how to resolve it?
That's up to you. Really! There is no correct answer to which thread should win the race. Usually, we "resolve" the problem by designing our programs so that their behavior doesn't depend on data races.
In your example, you have two threads that are trying to do two incompatible things. They both want to assign the same variable, but they disagree on what its value should be. That's a sign of Bad Design. It probably means that you haven't really thought about what that variable stands for in your program, or you haven't really thought about why or when it should ever be changed.
P.S., If a field of an Employee object holds an employee's ID, then it almost certainly should be a final field.
Suppose I have the following class:
#Component
public class MyComponent {
public Double calculateNodeSum(Node node) {
Double sum = node.getAmount();
for (Node child : node.getChildren()) {
if (!visited(child)) {
markNodeVisited(child);
sum += calculateNodeSum(child);
}
}
return sum;
}
}
Assumptions:
Assume that the node graph is not being modified while any of these calculations are occurring.
(Some methods such as visited and markNodeVisited have been left out). My question is this:
What is the best way (in terms of performance) to modify this class such that my calculateNodeSum method is thread safe? I can think of several:
add a private final Object lock = new Object(); field to the class, and synchronize the calculateNodeSum method using this lock object. Track the visited nodes using a class member field private Set<Node> visitedNodes. This would also require us to clear the visitedNodes we're tracking each time the method is called.
modify the calculateNodeSum method so that we initially create, and then pass a visitedNodes local variable of type Set<Node> around to track the visited nodes
use Spring's #Scope annotation to manage scope (request scope might work, as long as there aren't multiple threads per request calling this method)
some other solution that I haven't thought of
The best way is to NOT keep any state in the #Component, so no locking is needed. So state is only kept in local variables which are passed to other methods as arguments. So, I guess I would go for option 2.
The heart of the question is what you mean by thread-safe.
By thread-safe, I mean that I don't want my set of visited nodes to be corrupted.
I understand that. However, the code as given doesn't mutate the graph. (OK ... markNodeVisited(child) might do ... but if it does then your algorithm is inherently non-reentrant which moots the following ...)
Example: MyComponent is instantiated as a singleton bean (the Spring default). I have two threads A and B. Thread A calls calculateNodeSum with a tree structure that has one billion nodes. A fraction of a second later, Thread B calls calculateNodeSum with a subset of the nodes such that there is overlap in the nodes in thread A and thread B. I want the sum to be calculated correctly on each thread. Without some strategy for doing this safely, my list of visited nodes will be written by both threads.
Obviously, if you want simultaneous traversals, markNodeVisited has to record the "marks" in a way that each traversal uses an independent mark set. That is a given.
Here's the problem for getting "accurate" counts.
If the graph is being mutated, then you can only get sums that are instantaneously accurate if you can either block mutations or (effectively) snapshot the graph. Obviously, the getters need to be synchronized etc to avoid memory anomalies resulting from mutation during or prior to the traversal.
If the graph is not being mutated, then it is simply a matter of reading the node information in a thread-safe fashion. Making the relevant getters synchronized should be sufficient.
In summary - unless you are clear in your specification of the expected (non-threaded) behavior, what the threads are doing, and unless you provide the rest of the code, we can't really give you an answer on how to make the code thread-safe.
Thread-safety is defined in terms of correctness. Basically, it means that code that is correct when there is only one thread will also be correct when there are multiple threads. This all hinges on what you mean by correct. If you don't specify what "correct" means, "thread-safe" is not meaningful.
I've got some crazy task, that sounds like mission impossible. I need to pass some data through stack of methods, which I can't modify (can modify only the last one). Example:
SomeData someData; //not passed in method1
obj1.method1(...);
here is obj1 class code
obj1 {
someReturnClass method1(...) {
...
obj2.method2(...);
...
}
}
obj2 and method2 call some more methods, before they get to objN.methodM(). It can even be run in separate thread (so, ThreadLocal won't help). I need to access someData inside methodM, which is not passed through this stack as parameter.
I've got some concepts to get it through exception and double running methodM, but it looks ugly.
Do you have any ideas, how to pass someData to methodM()?
If you can't smuggle access any other way -- e.g. by adding a reference to SomeData into some other object that is passed through the call stack -- then you will eventually have to use a global variable. This is of course a poor design, but nothing else is possible given your constraints.
You mentioned in a comment that you may have several calls to your method "active" (is it recursive, or do you have multiple threads?) In that case, you will need to have a global collection instead, and have some way of inferring which element of the collection to select from the data that is passed through the call stack.
I understand that you need to access a local variable inside a method activation, of a method which you can't change, but which you know exists lower on the stack.
The obvious thing here is to work with the Java Debugging Architecture: http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/index.html
This will allow you to examine the stacks of all threads.
Finally, I found solution:
Create JAAS Subject
Subject subject = new Subject();
Put data somewhere in subject's principals or credentials:
subject.getPublicCredentials().add(new String("Trololo"));
Get this subject and it's data anywhere you need (works even in another thread):
Subject subject = Subject.getSubject(AccessController.getContext());
System.out.println(subject.getPublicCredentials());
It won't work only in one case: thread started before subject was created.
A simple example:
class Account{
private String account_name;
private String password;
private double balance;
public synchronized double getBalance(){
return balance;
}
public synchronized void setBalance(double add){
balance += add;
}
}
From my understanding that acquiring the lock associated with an object does not prevent other threads from accessing that object. They have to be the same lock to prevent accessing.
So if two person tried accessing the same account at different ATM, then it will create two different instances of this Account object, correct ? so then it's not guarded with the same lock, right ?
lets say if Person A (Thread A) tried to save money into the account while at the same time Person B(Thread B) tried getting to total balance of the account.
How does it work ? Do they cache the Account while be using so it will return the same Account object when the next request comes in ?
Synchronized methods will lock the object instance. However, if there is a method, which is not synchronized concurrent access can happen.
ATM machines don't access your account - the bank server does. The ATM machine is just a client. So accessing the same account from 2 different ATMs would be guarded by the bank server, which has only one instance of this account in it's memory / database (probably protected by some locking mechanism and not written in Java).
It depends on the way the system is implemented. Usually you have instances of a class and each instance has an implicit lock associated with it OR you can create a simple
private Object lock;
and then everyone (be it ATM or a bank employee or something else) MUST explicitly acquire this lock. At the end of the day it boils down how the system is designed and implemented - locking primitives are just that - primitives. It is up to the designer/implemented to make use of the and to utilize them appropriately in EVERY component - consistent locking. Furthermore in this case I'd go for an atomic double and save the trouble of acquiring a potentially heavy object lock.
My best guess is they are using a object pool like cache and when ever request comes it will search particular object(Account) exist in the pool by using some unique identifier like account number. If it exist reference will be returned. Other wise it will be loaded from persistent datasource to the pool and new reference will be created and returned. So even two users(threads) try to access it sametime. Server will not create two instances for each of them.
Secondly if there are multiple synchronzied methods with in a class and if a thread is currently executing inside a synchronized method all the other threads trying to access any synchronized method for same object will be blocked(suspended execution) until first thread exists the synchronized method.
From my understanding that acquiring the lock associated with an object does not prevent other threads from accessing that object. They have to be the same lock to prevent accessing.
Correct. If multiple threads attempt to acquire a simple lock, then only on will be allowed to proceed. Locks do not necessarily need to be associated with a single object though. You can creates locks for other tasks as well.
So if two person tried accessing the same account at different ATM, then it will create two different instances of this Account object, correct ? so then it's not guarded with the same lock, right ? lets say if Person A (Thread A) tried to save money into the account while at the same time Person B(Thread B) tried getting to total balance of the account. How does it work ? Do they cache the Account while be using so it will return the same Account object when the next request comes in ?
Sort of, what you're describing is a distributed locking scenario, which is quite different. As somebody already mentioned, the ATM will send the transaction back for processing at the bank, and the servers there will handle concurrency issues.
I am writing an application that uses the observer pattern. The client class needs to know when an Employee object's state changes. It also needs to know the state of the employee at the current time (before any updates have been made). At the moment i am using a getEmployee() method and then registering an employee observer:
public class MyClass implements EmployeeObserver{
...
Employee employee= subjectClass.getEmployee();
subjectClass.registerEmployeeObserver(this);
...
}
Is there anything wrong with combining these methods so that an Employee object is returned in the same method call that the observer is registered in? :
Employee employee = subjectClass.getAndObserveEmployee(this);
I know this may seem a bit strange, but i only need the getEmployee method when the observer class is initialised and the subjectClass already has quite a large interface that i want to keep to a minimum. So, is this acceptable or is it bad practice to combine two actions into a single method call?
It's cleaner to separate the two.
On a separate note, why does the Employee itself not have an addObserver() method? There could be a perfectly valid reason but that would be my first guess of where to find it if I were searching for it. Either that or there would be some kind of service that manages employees and has the addObserver(int employeeIdToObserver) or something like that (implying that you already have a reference to the employee before you observer it.
Also, one way you could write the pattern is...
public interface EmployeeObserver {
public void stateChanged(State oldState, State newState);
}
...for observers that need to know what the state was before the change.
If sometimes you don't need the employee you have to do
subjectClass.getAndObserveEmployee(this);
which looks strange. or if sometimes you need emploee but not to register:
Employee employee = subjectClass.getAndObserveEmployee(null);
which again is not nice. If, let say you want to change the register part, (i.e. one more arg), you have to change the places where you use the function only for get() also.
I would not do that, except if necessary like in case of
oldVal = ConcurrentMap.replaceValue();
in this case two operations must be combined in one method because in concurrent system between two calls the state can change.