Shouldnt a lock on class block threads from all class instances - java

public class Fern extends Thread
{
private String x = "varun";
public void run()
{
synchronized(Fern.class){
System.out.println(x);
try {
sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
x = "Anku";
}
}
public static void main(String args[]) throws Exception
{
Fern f = new Fern();
Thread t1 = new Thread(new Fern());
Thread t2 = new Thread(new Fern());
t1.start();
t2.start();
}
}
Output is:
varun
varun
Since the block has been synchronized on Fern.class, only one thread should be allowed to enter the block at a time irrespective of which instance it belongs to since there is only one lock for the class for all instances. If I replace new Fern() in the Thread constructor with a single Fern object, the output is:
varun
Anku.
The behaviour is what would have been had I synchronized on(this).
I dont understand why this is happening since I synchronized

x is not a static variable. Change it to static.
static String x = "varun";
EDIT:
or pass the same object as parameter to t1 and t2.
Fern f = new Fern();
Thread t1 = new Thread(f); // pass the same object
Thread t2 = new Thread(f);

x is an instance variable - in other words, even though only one thread can enter that block at a time, they're looking at different variables. Changing the value of x in the first thread doesn't affect the x that the second thread is looking at.
In other words, the synchronization is "correct" (if you don't want more than one thread to enter that block regardless of instance) but your data access isn't doing what you think it should.
As a side note, I personally prefer locking on references which only my class can see.
As another side note, it would be better if Fern implemented Runnable rather than extending Thread - you're currently passing one thread to another one's constructor, which doesn't make much sense...

The x in each instance of the thread is a different one. Try private static String x to use a shared x in both cases.

This has nothing to do with synchronization. x is an instance variable, so each Fern instance has its own copy, initialized to "varun", then printed, then set to "Anku".

Because you have two different Fern instances, the fact that one of them changes the value of its x field is not seen by the other. (I am guessing, since you don't give the declaration of x. To get better answers, post only complete code.)

Related

I don't understand how the Thread.sleep and 'new' operator work

There are two things that I did not clear, one concerns the new operator, the other, the method Thread.sleep.
// Create a second thread.
class NewThread implements Runnable {
Thread t;
NewThread() {
// Create a new, second thread
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start(); // Start the thread
}
// This is the entry point for the second thread.
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
class ThreadDemo {
public static void main(String args[]) {
new NewThread(); // create a new thread
try {
for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
I know that the new operator is used to allocate an object
for example: Box refvar=new Box(); call the constructor of Box class
in this case the call is new NewThread();
But I have no reference variable, I don't understand how Java call the constructor without reference variable. Normally I use: Nameofclass reference-variable-name = new NameOfConstructor();.
Another thing I do not understand is: how Java can call Thread.sleep() if there is no object with the name Thread? in this case should be: t.sleep(1000) or not?
Thanks in advance.
You can call a constructor without assigning a reference to it.
In your case, the field Thread t maintains a reference to the thread, so there will be no premature garbage collection.
Thread.sleep() sleeps the current thread; i.e. the thread that is currently executing that bit of code.
It is valid to create an object (new File()) without storing the object (File file = new File()). In that case you create the object and call the constructor but can't do anything with the result. In many cases this doesn't do much (but it could change static data or throw an exception).
In your case the constructor NewThread() actually creates a thread and starts it.
Your second question regarding Thread.sleep() actually calls the static function sleep in the class Thread, which will wait for the given time and then return. So this will actually sleep the current thread, and not another thread that you call it on. Note that even calling it on a thread object (someThread.sleep()) still sleeps the current thread and not someThread. In your example the current thread is the main thread (which is created by the JVM and eventually used to call the main function)
new NewThread();
Creates a new object with no reference in your main, therefore after the creation you are no more able to access this object within main. But the object is created anyway.
Thread.sleep(1000);
Secondly, sleep is a static method, therefore you can call this method directly with the classname, you do not need to instanciate an object of thread first for this.
Thread.sleep(...)
is possible because sleep is a static method which
Causes the currently executing thread to sleep (temporarily cease
execution) for the specified number of milliseconds, subject to the
precision and accuracy of system timers and schedulers.
according to the JavaDoc
1) new ClassName() will create an instance. Even if you can't refer to it later, you can call instance methods on that instance there itself.
2) Thread class has a static method called sleep() and static method doesn't require an instance. They can directly be called using the className.methodName()
Thread#sleep always affects only the current thread. You are not allowed to target other threads in order to put them to sleep. Calling t.sleep() results in the static method being called, which affects the current thread. Calling static methods on an instance is a bad idea, it is likely to mislead people who read the code into thinking the code is putting another thread to sleep.
Your NewThread creates a thread in the constructor. Once you start a thread it will run until it terminates, regardless of if anything else has a reference to it. Each thread is a GC root that prevents garbage collection of anything that it references. Keeping a reference to the thread would allow you to interrupt it or otherwise communicate with it.
The posted code looks like it was created by somebody who had heard that using Runnable was preferred over extending Thread, but who had missed the point about why. Having a Runnable create a thread for itself defeats the purpose of separating Runnables (the tasks that need to be executed) from the means of executing the tasks (the threads). This is not a good way to design any real code for a purpose other than causing confusion.
Generally Thread Created 2-way,
1. extends Thread class
2. implements Runnable interface.
Here, you have choose option-2, e.g. Runnable Interface.
In your code,
you have first Created new Thread(...) with new keyword, which is wrap-in Runnable object inside it.
Answer-2 :
Thread.sleep() method : it's pause current thread's execution, while executing it, current thread move to Wait/Block state from Running State of thread life-cycle.
After completion of N-millisecond (here 500, i.e. 0.5 sec.).
that thread again wake up it and comes to Runnable state.
Let me know, if still any query.

What does it mean to have a synchronized block on a different monitor than 'this' instance?

I have the following piece of code. It has two objects, namely MultiThreadingTest, and the ThreadB object. When we say synchronized(b), what does it mean exactly? Can the 'main' thread get a lock on b before ThreadB finishes it's execution? I can't understand the significance of monitor object in the synchronized block.
package threads;
class MultiThreadingTest
{
public static void main(String[] args)
{
ThreadB b = new ThreadB();
b.setName("Thread B");
b.start();
synchronized(b)
{
System.out.println("Current thread : "+ Thread.currentThread().getName());
try
{
System.out.println("Waiting for b to complete...");
b.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Total = "+b.total );
}
}
}
class ThreadB extends Thread
{
int total;
public void run()
{
synchronized(this)
{
System.out.println("Current thread : "+Thread.currentThread().getName());
for(int i=0;i<100;i++)
{
total = total + i;
}
notify();
}
}
}
Think of it like the child's game, whoever holds the [whatever object] gets to speak. Whoever holds the monitor object gets to execute in computing terms.
The monitor is the object you are locking upon, at any given time, only one thread accesses code protected by a synchronization block per monitor object. The object itself is arbitrary and doesn't hold much weight onto synchronization (though you have to watch out for reassigning variables as well as null references). Also, JB Nizet raises a good point here on synchronizing on a Thread object since many internal VM methods do that, you can cause bazaar, hard to detect bugs and deadlocks.
Two threads entering different synchronization blocks locking on different monitors will execute concurrently, analogous to two separate groups of people playing/enacting the "who ever holds to xxx gets to speak" game. Locking on this is just a convenient way to manifest a single lock synchronization without creating additional lock objects.
In your case, ThreadB b is the same object pointed to as this from within the ThreadB class meaning that only one thread can enter any of your defined synchronization blocks at once. The order is highly dependent on which thread ran first, the thread scheduler and even the underlying system.
The main reason for monitor objects is so that complex thread-safety mechanisms can be realized. Imagine a system where every synchronization block is single thread access (i.e. at any time, any thread enters a synchronization block will hold every other thread in the whole VM trying to enter a sync block) not only will this cause a massive performance slowdown, it just doesn't make sense. Why should two unrelated application modules lock on each other if they share no data and never interact?
The solution of course is to have one module use one (or several) monitor objects that are unrelated/unassociated with the other module, so both can execute concurrently independent of each other (assuming this is the desired behavior).
To further clarify, you could write:
class MultiThreadingTest{
public static void main(String[] args){
ThreadB b = new ThreadB();
b.setName("Thread B");
b.start();
synchronized(b.lock){
System.out.println("Current thread : "+ Thread.currentThread().getName());
try{
System.out.println("Waiting for b to complete...");
b.lock.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total = " + b.total );
}
}
}
class ThreadB extends Thread{
public final Object lock = new Object();
int total;
public void run(){
synchronized(lock){
System.out.println("Current thread : "+Thread.currentThread().getName());
for(int i = 0; i < 100; i++){
total = total + i;
}
lock.notify();
}
}
}
to exactly the same effect as the code you've used (even better, since it resolves the conflict with Thread.join() and other methods).
synchronized(this) means that you won't be able to enter this block of code if another thread is inside a block of code that is also synchronized on the object referenced by this.
synchronized(b) means that you won't be able to enter this block of code if another thread is inside a block of code that is also synchronized on the object referenced by b.
They thus do the exact same thing. The only difference is the object that is used to lock.
Note that waiting, synchronizing and notifying on an object of type Thread is a really really bad idea. It confuses things, and will lead to unwanted behavior because other methods (join() for example) also use the Thread as a monitor.
As per my understanding, no. The 'this' object within the run() method and the 'b' object in the main() method are the same.
Hence it would not be possible for the 'main' thread to acquire the lock until the thread completes execution.
Also the notify() within the run() method seems to be redundant in this case since its at the end of the method and the lock on the monitor would be relinquished any how.
PS: Do look around for similar questions that may already have been asked in the forum. They may help in providing additional understanding.

Confusion Regarding java threads on same/different objects

public class Computation extends Thread {
private int num;
private boolean isComplete;
public Computation(int nu) {
num = nu;
}
public void run() {
System.out.println("Thread Called is: " + Thread.currentThread().getName());
}
public static void main(String... args) {
Computation [] c = new Computation[4];
for (int i = 0; i < 3; i++) {
c[i] = new Computation(i);
c[i].start();
}
}
}
My Question is in main function we are creating every time a new Computation object on which the thread is being started then why we need to snchrnoized the run method? As we know for every different class object 'this' reference is different so we don't need to synchronize.
Also in another Example:
public class DiffObjSynchronized implements Runnable {
#Override
public void run() {
move(Thread.currentThread().getId());
}
public synchronized void move(long id) {
System.out.print(id + " ");
System.out.print(id + " ");
}
public static void main(String []args) {
DiffObjSynchronized a = new DiffObjSynchronized();
/**** output ****/
// 8 9 8 9
new Thread(a).start();
new Thread(new DiffObjSynchronized()).start();
}
}
Here is second example just like first we create a Thread on 2 different instances of class. Here we synchronize the move() method but by definition:
"two different objects can enter the synchronized method at the same time"
Please share your feedback?
If I understand you correctly, your question is: "Why is the move method synchronized?"
The answer is: it shouldn't be, for two reasons:
It doesn't access any fields, so there is nothing that could be corrupted by having many threads inside that method at once.
Each thread gets a different instance of the object, and thus a different lock. So the synchronized modifier makes no difference. Each thread can still enter its own instance's move method because they have separate locks.
You only need to synchronize when you have some data which is being shared between threads, and at least one thread is modifying that data.
Your threads are operating on different objects since you create a new instance for each thread. The intrinsic lock used by synchronized belongs to the instance. So the synchronized methods entered by your threads are guarded by different locks.
You need to understand how synchronization works.
Threads take a 'lock' on the object on which you are synchronizing when they enter the synchronized block. If you have a synchronized method then in that case the object becomes the 'this' instance. Now, no 2 threads can take a lock on the same object at the same time. object locks are mutex based in philosophy so only once thread can hold the mutex at a time. When the thread holding the lock exits the synchronized method or the block, it releases the mutex and thus the object lock becomes available to other threads to request lock on.
This link explains the concepts excellently. It has pictures about disassembled byte code which shows how threads take and leave locks and why 2 threads on 2 different object dont block each other.

What is the use of taking a lock on an object in synchronized block, if it can be accessed in any other method?

If there is a synchronized block which is taking lock on an object, say StringBuilder sb, which one thread is executing this synchronized block in which sb is locked, suppose there is another thread which is calling another method which will try to change the value of sb(not in synchronized block), then, will it be allowed to do that?
public static void main(String[] args) {
A a = new A();
new Thread(new MyRunnable(a), "T1").start();
new Thread(new MyRunnable(a), "T2").start();
}
static class MyRunnable implements Runnable {
A a;
public MyRunnable(A a) {
super();
this.a = a;
}
#Override
public void run() {
while (true) {
if ("T1".equals(Thread.currentThread().getName())) {
a.m1();
} else {
a.m2();
}
}
}
}
static class A {
StringBuilder abc = new StringBuilder("fdfd");
public void m1() {
synchronized (abc)
{
System.out.println("abc locked : " + abc);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();}
System.out.println("abc released: " + abc);
}
}
public void m2() {
System.out
.println(Thread.currentThread().getName() + " running");
System.out.println("trying to access abc");
abc.append("A");
System.out.println("abc accessed");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();}
}
}
}
I thought locking an object would not allow to change that object as well from being modified or accessed. But, from output I am seeing the locked object can be modified:
OUTPUT:
abc locked : fdfd
T2 running
trying to access abc
abc accessed
T2 running
trying to access abc
abc accessed
T2 running
trying to access abc
abc released: fdfdAA
abc accessed
abc locked : fdfdAAA
T2 running
I am not getting this, can anybody please explain this. What is the use of taking a lock on an object? Is it just because wait/notify/notifyAll methods?
If there is a synchronized block which is taking lock on an object, say StringBuilder sb, which one thread is executing this synchronized block in which sb is locked, suppose there is another thread which is calling another method which will try to change the value of sb(not in synchronized block), then, will it be allowed to do that?
Uh yes. I think you need to do some reading about what synchronized does. See the Java tutorial. It does not "lock" an object as in restrict other threads from operating on it. What it does is provide mutex for the surrounded block of code for threads that lock on the same object instance. The fields in an object are perfectly able to be mutated both inside or outside the synchronized block.
It is always a good idea to synchronize on a constant object so I tend to do something like:
private final Object lock = new Object();
...
synchronized (lock) {
// only one thread allowed inside this block at a time
}
If multiple threads are accessing some sort of thread-unsafe object, I will synchronize on that object and do the operations on the object inside the synchronized block:
private final SomeUnsafeObject someObject = ...;
...
synchronized (someObject) {
// only one thread allowed inside this block at a time
someObject.someUnsafeMethodCall(...);
}
// no accesses (read or write) outside of the synchronized block
I thought locking an object would not allow to change that object as well from being modified or accessed. But, from output I am seeing the locked object can be modified:
No, there is no implicit blocking of the object being changed. If you only access the object's fields inside of the synchronized block then you would have accomplished what you want.
public void m2() {
...
abc.append("A");
Right, since you are not inside of a synchronized (abc) block here, there is nothing that stops the thread from calling abc.append(...).
I am not getting this, can anybody please explain this. What is the use of taking a lock on an object? Is it just because wait/notify/notifyAll methods?
Synchronization allows you to control access to a block of code to one thread at a time based on the lock object (or the monitor on that object to be precise). It also allows you to do lock.wait(...) and lock.notify(...) to control the threads operation and block/release them as well.
Synchronization also puts up memory barriers so that a thread will see changes stored to central memory when it enters a synchronized block and will see it's changes written to central memory when it leaves. Without these memory barriers, if other threads access the StringBuilder without synchronization then they may seem some partially updated portion of that class which can cause NPEs or other failures.
A thread will only have to wait to access a locked code region, if that lock is held by another thread. However, it doesn't have to wait if it doesn't need a lock, i.e., your StringBuilder instance is only safe if every access is surrounded by a synchronized block locking on the same lock.
In your case, since access to abc in method m2() is not in synchronized block, a thread doesn't need a lock, and hence can access it.
When you are synchronizing on a Lock object the lock object has to be accessible by all threads, so either use a static object or a field belonging to the calling code.
Then you code will work to have only only one thread at a time accessing a certain block(s) of code. It will not prevent you acting in that code in anyway that you wish, but only one Thread can do it at one time.

Why does this throw an IllegalMonitorStateException?

I am getting into Java multithreading. I am very familiar with C/C++ pthreads, but am having issues with the Java notify() and wait() functions.
I understand that an IllegalMoinitorStateException is only thrown when a thread that doesnt "own" (aka hasnt synchronized) calls notify/wait.
When writing my application, I ran into this issue. I isolated the problem with the following test code:
public class HelloWorld
{
public static Integer notifier = 0;
public static void main(String[] args){
notifier = 100;
Thread thread = new Thread(new Runnable(){
public void run(){
synchronized (notifier){
System.out.println("Notifier is: " + notifier + " waiting");
try{
notifier.wait();
System.out.println("Awake, notifier is " + notifier);
}
catch (InterruptedException e){e.printStackTrace();}
}
}});
thread.start();
try{
Thread.sleep(1000);
}
catch (InterruptedException e){
e.printStackTrace();
}
synchronized (notifier){
notifier = 50;
System.out.println("Notifier is: " + notifier + " notifying");
notifier.notify();
}
}
}
This outputs:
Exception in thread "main" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at HelloWorld.main(HelloWorld.java:27)
I believe I have already acquired the lock on the notifier object. What am I doing wrong?
Thanks!
EDIT:
From this possible duplicate(Synchronizing on an Integer value), it seems that it is not a good idea to synchronize on an Integer because it is hard to make sure you are synchronizing on the same instance. Since my integer I am synchronizing on is a global visibile static integer, why am I getting different instances?
Because of notifier = 50; you are calling notifier.notify(); on a different object.
Initially when you calling synchronized on notifier in non-main Thread it was referencing to the object on heap whose content was 0 hence the thread owns that object . Now after non-main thread is put on wait using notifier.wait the control is given to the main thread . There after acquiring lock on object of Integer containing value 0 you made the notifier to refer the other object on heap memory containing value 50 because notifier = 50; is actually equivalent to notifier = new Integer(50) which means a new object of Integer is created and its reference is passed to notifier. Now , when the thread sees notifier.notify it looks that the Main thread now no longer owns the original object that it had acquired before. So IllegalMonitorStateException is throwing.
Just to add more information, you should never synchronize on a non-final object.
You need to synchronize on a constant object. If you synchronized on any object that you are assigning (i.e. changing the object) then the object is not constant and once it assigns the object and tries to notify on it, you will get the IllegalMonitorStateException. It also means that because they are synchronizing on different objects, multiple threads will be entering the protected block at the same time and race conditions will happen.
Since my integer I am synchronizing on is a global visibile static integer, why am I getting different instances?
When you assign a value to an Integer it changes it to a different object reference -- even if it is static. You are not changing the same object because Integer can't be mutated. So notifier = 50; assigns it to a different object than notifier = 0;.
If you want to use, for example, a constant object you can use an AtomicBoolean:
public static final AtomicInteger notifier = new AtomicInteger(0);
...
synchronize (notifier) {
notifier.set(50);
...
}
Here, AtomicInteger can be marked final because it's the same object all of the time.
For more information, see: Why is it not a good practice to synchronize on Boolean?

Categories