Java Threads and synchronization - java

I have a web app that uses some jars written by me.
My challenge is that i have a critical (but fast) section in my code.
1 - I have an object of a given class that has a couple of static fields. Let's call this class A
2 _ A exposes a not static method that access the static fields. for reading and writting. Lets call this method doJob.
3 - Every request instantiates an object of the class A and calls doJob.
A a = new A(); a.doJob();
4 - I assume that every request is creating a new Thread where doJob is executed.
5 - If I define doJob as public synchronized void doJob () {//Do the job} only one Thread at a time will be executing the method and the others will keep waiting.
The question is: Is it all right what i am saying?

You are right, but doJob will be synchronized at instance level, so doJob method could be executed in the same time by two or more different threads on two or more instances of class A. If you want doJob to be executed only by one thread at a time (e.g because it chages static fields) you should either declare it static or synchronize the whole method body using a static field as locking object.

Given that you're trying to guard static (i.e. one per class) fields with non-static (i.e. one per object) monitors, I would say that the "only one thread at a time will be executing the method and the others will keep waiting" claim does not hold.

No.
Marking an instance method as synchronized means the same that doing
public void myMethod() {
synchronized(this) {
...
}
}
So, you can only guarantee that two threads are not running the same method of the same object. The same method from another object can be run simultaneously.
Try to synchronize with a more "static" object. I would use the class object itself, or some static (and inmutable) member.

yes, you're outline is correct. and it does technically bottleneck the system while the other threads wait for access. and this is perfectly fine and normal as long as you avoid putting any heavy processing or i/o within the synchronized block.

Related

java: running thread methods in the same class

I have three threads on the same class i.e
Thread A obj, Thread B obj, Thread C obj and that class contains 3 static synchronized methods so when we start the 3 threadssaya.meth1, b.meth2, c.meth3what will happen – does all three will execute or only one ?`
Update:
interviewr asked me this question so actually i do have any code to write it here
The methods are static and synchronized.. So, the lock will be on the class object.. Not on the instances of the class.. So the methods will run one after another.... Thread2 and Thread3 will have to wait until thread1 completes method1().. syncronization is NOT at method level.. it is always at object level... beit instance object or class object.
then they will execute it one by one in serial manner as the methods are static synchronized. So the lock will be held at Class Level not the method level. Hence one thread will acquire lock and others will have to wait.
You should try running this and see.
Once you invoke a synchronized method, the VM will automatically ask a grant of access for the object on which you are invoking the method. If that is given it will enter the synchronized method. Upon exit til will release this access right. While holding the rights, no-one else is allowed into any synchronized method on the same object, effectively serializing the requests.
does that make sense?
Synchronization is designed to make things thread-safe and avoid race conditions, and this fashion reduce access to at most one thread. There is no way for the program to find out whether two synchronized methods A and B are otherwise connected, so it has the policy of least tolerance.
If you have more synchronization that necessary, e.g. that A and B needs to be mutually exclusive and C and D needs to be mutually exclusive, but not between, say A and C then the advice is typically to modularise your code so A+B goes into one object while C+D goes into another, hence avoiding to step over each others toes
If execution for objects of the same class attempt to enter the same synchronized method (whether static or not)from different threads, they will be synchronized (i.e. execute one at a time).
The primary difference between static synchronized methods and non static synchronized methodsis that non-static synchronized methods hold a lock on the instance of the class whereas static synchronized methods lock on the class object.
Since in java there exists one class object per class, only one thread can execute inside a static synchronized method in the same class.
For non-static synchronized methods only one thread can execute inside a static synchronized method in the same object
And one more point is that synchronization is at object level not as method level.

Do static methods block?

Let's say I have a class defined as:
public class MyClass {
private static int data;
public static staticMethod(int val){
... do something with data based on val ...
}
}
And now let's say I have many Java threads running in my application that make calls to the static method
MyClass.staticMethod(int)
Will the method block upon each invocation? i.e., if thread 1 calls the method first and while that run of the method is being executed, thread 2 calls the static method, will the second thread have to wait until the first execution is completed?
If the answer is no, then when would it make sense to use static data members in a un-"synchronized" way?
No, that is not part of the static keyword. If you want to synchronize two threads accessing the same method, use other possibilities, such as synchronized (method or statement), or stuff from the java.util.concurrent package.
Will the method block upon each invocation?
No. A plain static method doesn't block other threads. (But a static synchronized method can block other threads ... or be blocked by other threads.)
If the answer is no, then when would it make sense to use static data members in a un-"synchronized" way?
It is OK if the data member if the member is volatile ... modulo the limits of volatile.
It is OK if the data member is a final reference to an thread-safe type.
It is OK if the data member is thread confined. (This is unlikely since the member is visible to all threads by virtue of being static. But it is possible.)
It is OK if something else is taking care of synchronization, or if you are using Lock objects for mutual exclusion, etcetera ... though you probably would say that these "don't count".
As you have written it, no. Multiple threads will not block until another thread has finished the method execution. This is true regardless of whether the method is static.
To enforce that only a single thread has access to the method, you must make the method synchronized.
public static synchronized staticMethod(){
No, not unless the class/method is declare Synchronized.
http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html

Can a class with getters separate from input processing methods be considered "thread-safe"?

I was reading though a book on Java and there was this exercise question where they declared a class with one private variable, one public void method that did some expensive operation to calculate and then set the private variable, and a second public method to return the private variable. The question was "how can you make this thread-safe" and one possible answer was "synchronize each of the two methods" and one other possible answer was "this class can not be made thread-safe".
I figured the class could not be made thread-safe since even if you synchronize both methods, you could have a situation that Thread1 would invoke the setter and before Thread1 could invoke the getter, Thread2 might execute and invoke the setter, so that when Thread1 went and retrieved the result it would get the wrong info. Is this the right way to look at things? The book suggested the correct answer was that the class could be made thread safe by synchronizing the two methods and now I'm confused...
I figured the class could not be made thread-safe since even if you synchronize both methods, you could have a situation that Thread1 would invoke the setter and before Thread1 could invoke the getter, Thread2 might execute and invoke the setter, so that when Thread1 went and retrieved the result it would get the wrong info. Is this the right way to look at things?
You are correct with this. There is no way to guarantee that a thread will not have called either of the methods in between your calls of each of the methods, from within the class.
If you do want to do this, that will require a wrapper class.
So if the class with the getter and setter is like so:
class Foo
{
private static int bar;
public static synchronized void SetBar(int z) { ... }
public static synchronized int GetBar() { ... }
}
The wrapper class would look something like this:
class FooWrapper
{
public synchronized int SetGetBar(int z)
{
Foo.SetBar(z);
return Foo.GetBar();
}
}
The only way to guarantee this will work is if you can guarantee that all calls will go through your wrapper class rather than directly to class Foo.
When you make those two synchronized, the getter and setter themselves are thread-safe. More specifically:
When you call the setter, you are guaranteed that the value of the variable is what you set it to when the method finishes.
When you call the getter, you are guaranteed that the return value is the value of the variable when you made the call.
However, making the getter and setter themselves thread-safe does not mean that the application as a whole (i.e. whatever is using this class) is thread-safe. If your thread wants to call a setter then get the same value upon invoking the getter, that involves synchronization on a different level.
As far as thread-safety is concerned, a thread-safe class need not control how its methods are invoked (for example, it need not control which way the threads interleave their calls), but it needs to ensure that when they are, the methods do what they are supposed to.
synchronized in Java is an object-wide lock. Only one synchronized method of any given object can be executed on any given thread at a time. Let's have this class:
class Foo
{
private int bar;
public synchronized void SetBar() { ... }
public synchronized int GetBar() { ... }
}
Thread 1 calls SetBar(). Thread 1 acquires the object lock.
Thread 2 wants to call SetBar(), but Thread 1 holds the lock. Thread 2 is now queued to acquire the lock when Thread 1 will release it.
Thread 1 finishes executing SetBar() and releases the lock.
Thread 2 immediately acquires the lock and starts executing SetBar().
Thread 1 calls GetBar(). Thread 1 is now queued to acquire the lock when Thread 2 will release it.
Thread 2 finishes executing SetBar() and releases the lock.
Thread 1 acquires the lock, executes GetBar(), and is done with it.
You did the work twice, but you didn't cause any race condition. It may or may not be erroneous to do the work twice, depending on what it is.
A frequent pattern is to have one thread produce content and one other thread do something useful with it. This is called the producer-consumer pattern. In this case, there is no confusion over who or what tries to SetBar() and what tries to GetBar().

Instance methods and thread-safety of instance variables

I would like to known if each instance of a class has its own copy of the methods in that class?
Lets say, I have following class MyClass:
public MyClass {
private String s1;
private String s2;
private String method1(String s1){
...
}
private String method2(String s2){
...
}
}
So if two differents users make an instance of MyClass like:
MyClass instanceOfUser1 = new MyClass();
MyClass instanceOfUser2 = new MyClass();
Does know each user have in his thread a copy of the methods of MyClass? If yes, the instance variables are then thread-safe, as long as only the instance methods manipulate them, right?
I am asking this question because I often read that instance variables are not thread-safe. And I can not see why it should be like that, when each user gets an instance by calling the new operator?
Each object gets its own copy of the class's instance variables - it's static variables that are shared between all instances of a class. The reason that instance variables are not necessarily thread-safe is that they might be simultaneously modified by multiple threads calling unsynchronized instance methods.
class Example {
private int instanceVariable = 0;
public void increment() {
instanceVariable++;
}
}
Now if two different threads call increment at the same then you've got a data race - instanceVariable might increment by 1 or 2 at the end of the two methods returning. You could eliminate this data race by adding the synchronized keyword to increment, or using an AtomicInteger instead of an int, etc, but the point is that just because each object gets its own copy of the class's instance variables does not necessarily mean that the variables are accessed in a thread-safe manner - this depends on the class's methods. (The exception is final immutable variables, which can't be accessed in a thread-unsafe manner, short of something goofy like a serialization hack.)
Issues with multi-threading arise primarily with static variables and instances of a class being accessed at the same time.
You shouldn't worry about methods in the class but more about the fields (meaning scoped at the class level). If multiple references to an instance of a class exist, different execution paths may attempt to access the instance at the same time, causing unintended consequences such as race conditions.
A class is basically a blueprint for making an instance of an object. When the object is instantiated it receives a spot in memory that is accessed by a reference. If more than one thread has a handle to this reference it can cause occurrences where the instance is accessed simultaneously, this will cause fields to be manipulated by both threads.
'Instance Variables are not thread safe' - this statement depends on the context.
It is true, if for example you are talking about Servlets. It is because, Servlets create only one instance and multiple threads access it. So in that case Instance Variables are not thread safe.
In the above simplified case, if you are creating new instance for each thread, then your instance variables are thread safe.
Hope this answers your question
A method is nothing but a set of instructions. Whichever thread calls the method, get a copy of those instructions. After that the execution begins. The method may use local variables which are method and thread-scoped, or it may use shared resources, like static resources, shared objects or other resources, which are visible across threads.
Each instance has its own set of instance variables. How would you detect whether every instance had a distinct "copy" of the methods? Wouldn't the difference be visible only by examining the state of the instance variables?
In fact, no, there is only one copy of the method, meaning the set of instructions executed when the method is invoked. But, when executing, an instance method can refer to the instance on which it's being invoked with the reserved identifier this. The this identifier refers to the current instance. If you don't qualify an instance variable (or method) with something else, this is implied.
For example,
final class Example {
private boolean flag;
public void setFlag(boolean value) {
this.flag = value;
}
public void setAnotherFlag(Example friend) {
friend.flag = this.flag;
}
}
There's only one copy of the bytes that make up the VM instructions for the setFlag() and setAnotherFlag() methods. But when they are invoked, this is set to the instance upon which the invocation occurred. Because this is implied for an unqualified variable, you could delete all the references to this in the example, and it would still function exactly the same.
However, if a variable is qualified, like friend.flag above, the variables of another instance can be referenced. This is how you can get into trouble in a multi-threaded program. But, as long as an object doesn't "escape" from one thread to be visible to others, there's nothing to worry about.
There are many situations in which an instance may be accessible from multiple classes. For example, if your instance is a static variable in another class, then all threads would share that instance, and you can get into big trouble that way. That's just the first way that pops into my mind...

Constructor synchronization in Java

Someone somewhere told me that Java constructors are synchronized so that it can't be accessed concurrently during construction, and I was wondering: if I have a constructor that stores the object in a map, and another thread retrieves it from that map before its construction is finished, will that thread block until the constructor completes?
Let me demonstrate with some code:
public class Test {
private static final Map<Integer, Test> testsById =
Collections.synchronizedMap(new HashMap<>());
private static final AtomicInteger atomicIdGenerator = new AtomicInteger();
private final int id;
public Test() {
this.id = atomicIdGenerator.getAndIncrement();
testsById.put(this.id, this);
// Some lengthy operation to fully initialize this object
}
public static Test getTestById(int id) {
return testsById.get(id);
}
}
Assume that put/get are the only operations on the map, so I won't get CME's via something like iteration, and try to ignore other obvious flaws here.
What I want to know is if another thread (that's not the one constructing the object, obviously) tries to access the object using getTestById and calling something on it, will it block? In other words:
Test test = getTestById(someId);
test.doSomething(); // Does this line block until the constructor is done?
I'm just trying to clarify how far the constructor synchronization goes in Java and if code like this would be problematic. I've seen code like this recently that did this instead of using a static factory method, and I was wondering just how dangerous (or safe) this is in a multi-threaded system.
Someone somewhere told me that Java constructors are synchronized so that it can't be accessed concurrently during construction
This is certainly not the case. There is no implied synchronization with constructors. Not only can multiple constructors happen at the same time but you can get concurrency issues by, for example, forking a thread inside of a constructor with a reference to the this being constructed.
if I have a constructor that stores the object in a map, and another thread retrieves it from that map before its construction is finished, will that thread block until the constructor completes?
No it won't.
The big problem with constructors in threaded applications is that the compiler has the permission, under the Java memory model, to reorder the operations inside of the constructor so they take place after (of all things) the object reference is created and the constructor finishes. final fields will be guaranteed to be fully initialized by the time the constructor finishes but not other "normal" fields.
In your case, since you are putting your Test into the synchronized-map and then continuing to do initialization, as #Tim mentioned, this will allow other threads to get ahold of the object in a possibly semi-initialized state. One solution would be to use a static method to create your object:
private Test() {
this.id = atomicIdGenerator.getAndIncrement();
// Some lengthy operation to fully initialize this object
}
public static Test createTest() {
Test test = new Test();
// this put to a synchronized map forces a happens-before of Test constructor
testsById.put(test.id, test);
return test;
}
My example code works since you are dealing with a synchronized-map, which makes a call to synchronized which ensures that the Test constructor has completed and has been memory synchronized.
The big problems in your example is both the "happens before" guarantee (the constructor may not finish before Test is put into the map) and memory synchronization (the constructing thread and the get-ing thread may see different memory for the Test instance). If you move the put outside of the constructor then both are handled by the synchronized-map. It doesn't matter what object it is synchronized on to guarantee that the constructor has finished before it was put into the map and the memory has been synchronized.
I believe that if you called testsById.put(this.id, this); at the very end of your constructor, you may in practice be okay however this is not good form and at the least would need careful commenting/documentation. This would not solve the problem if the class was subclassed and initialization was done in the subclass after the super(). The static solution I showed is a better pattern.
Someone somewhere told me that Java constructors are synchronized
'Somebody somewhere' is seriously misinformed. Constructors are not synchronized. Proof:
public class A
{
public A() throws InterruptedException
{
wait();
}
public static void main(String[] args) throws Exception
{
A a = new A();
}
}
This code throws java.lang.IllegalMonitorStateException at the wait() call. If there was synchronization in effect, it wouldn't.
It doesn't even make sense. There is no need for them to be synchronized. A constructor can only be invoked after a new(), and by definition each invocation of new() returns a different value. So there is zero possibility of a constructor being invoked by two threads simultaneously with the same value of this. So there is no need for synchronization of constructors.
if I have a constructor that stores the object in a map, and another thread retrieves it from that map before its construction is finished, will that thread block until the constructor completes?
No. Why would it do that? Who's going to block it? Letting 'this' escape from a constructor like that is poor practice: it allows other threads to access an object that is still under construction.
You've been misinformed. What you describe is actually referred to as improper publication and discussed at length in the Java Concurrency In Practice book.
So yes, it will be possible for another thread to obtain a reference to your object and begin trying to use it before it is finished initializing. But wait, it gets worse consider this answer: https://stackoverflow.com/a/2624784/122207 ... basically there can be a reordering of reference assignment and constructor completion. In the example referenced, one thread can assign h = new Holder(i) and another thread call h.assertSanity() on the new instance with timing just right to get two different values for the n member that is assigned in Holder's constructor.
constructors are just like other methods, there's no additional synchronization (except for handling final fields).
the code would work if this is published later
public Test()
{
// Some lengthy operation to fully initialize this object
this.id = atomicIdGenerator.getAndIncrement();
testsById.put(this.id, this);
}
Although this question is answered but the code pasted in question doesn't follow safe construction techniques as it allows this reference to escape from constructor , I would like to share a beautiful explanation presented by Brian Goetz in the article: "Java theory and practice: Safe construction techniques" at the IBM developerWorks website.
It's unsafe. There are no additional synchronization in JVM. You can do something like this:
public class Test {
private final Object lock = new Object();
public Test() {
synchronized (lock) {
// your improper object reference publication
// long initialization
}
}
public void doSomething() {
synchronized (lock) {
// do something
}
}
}

Categories

Resources