Confusion Regarding java threads on same/different objects - java

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.

Related

Java: Multithreading inconsistency [duplicate]

I have a thread class which implements runnable and an int counter as instance variable. Two synchronized methods add and sub. When I run my test class somehow it is printing wrong results once in couple of times. As far as I understand when a method is synchronized, entire object will be locked for accessing by other threads, with this logic every time we should get same results right? Some how that is not the case. Am I missing something?
My machine is Windows 7, 64 bit.
public class ThreadClass implements Runnable {
int counter = 0;
#Override
public void run() {
add();
sub();
}
public synchronized void add() {
System.out.println("ADD counter" + (counter = counter + 1));
}
public synchronized void sub() {
System.out.println("SUB counter" + (counter = counter - 1));
}
}
Testclass
public class ThreadTest {
public static void main(String args[]) {
ThreadClass tc = new ThreadClass();
Thread tc0 = new Thread(tc);
tc0.start();
tc0.setPriority(Thread.MAX_PRIORITY);
Thread tc1 = new Thread(tc);
tc1.start();
tc1.setPriority(Thread.NORM_PRIORITY);
Thread tc2 = new Thread(tc);
tc2.start();
tc2.setPriority(Thread.MIN_PRIORITY);
}
}
Results
ADD counter1
ADD counter2
SUB counter1
SUB counter0
ADD counter1
SUB counter0
Note: You may need to do couple of runs to produce this inconsistency.
Your results look correct.
During the execution of the methods, an exclusive lock on the object is obtained, but between the add() and sub() calls, the threads can freely interleave.
If you end up with a total of 0 after all the threads have run, then none of them overwrote eathother and the access to counter was synchronized.
If you wish to have counter only go from 0 to 1 sequentially and never hit 2, then do the following (which will render the method-level synchronization redundant so long as no other classes are involved):
#Override
public void run() {
synchronize(this) {
add();
sub();
}
}
However, this makes the whole point of the threads useless since you could do that in a single-threaded loop.
Synchronization will indeed mean that all threads will block waiting to acquire a lock before they can enter the synchronized block. Only one thread can ever have the lock on the object, so only one thread can be in the add() or sub() methods.
However, this does not imply anything else about the ordering of threads. You're starting three threads - the only guarantee is that they won't stomp on each other by running the add or sub methods at once. Thread 1 can call add(), then thread 3 can call add(), then thread 2 can call add(), then they can all call sub(). Or they could all call add() and then sub() each. Or any mixture - the only requirement being that each thread calls add() before it calls sub() and that no two threads will ever call add() or sub() while another thread is in that method.
Aside: it can be, in some cases, bad form to synchronize on this, as it's public - it's often preferred to use an internal private Object to lock on so that no other callers can take your lock and violate any locking strategies you have designed.
There is nothing wrong with either set of results. They are both perfectly consistent with what your code does. The running order of multiple threads is not guaranteed.
Your 'synchronized' methods ensure you get valid results -- each call to add in fact adds one and each call to sub in fact subtracts one. Without them, you could get a final result other than zero.

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.

Does Java monitor include instance variables?

Is it that monitor in Java does not restrict access to instance variables and only to the methods which are declared synchronized or code in synchronized statements?
I have created two threads, thread y invokes sync() method, which is declared synchronized while thread r invokes unsync() method which is not declared synchronized. Both invoke methods on shared object s.
Thread r is able to modify the instance variable of object s while the monitor or lock of that object is still being held by the thread y.
Is it that the monitor in Java does not restrict access to instance variables, and only to the methods which are declared synchronized or code in synchronized statements?
public class Stuff {
private int a = 10;
public synchronized void sync() {
long t1 = System.currentTimeMillis();
System.out.println("Okay, I am in sync() method. "
+ "I will be waiting for 10 seconds. Current Time = "
+ System.currentTimeMillis());
while (System.currentTimeMillis() - t1 < 10000);
System.out.println("Okay, I have waited for 10 seconds. Current time is "
+ System.currentTimeMillis()
+ ". Now I will exit from sync() method, a = " + this.a);
}
public void unsync() {
System.out.println("Alright, I am in unsync() method. The current time is "
+ System.currentTimeMillis());
this.a = this.a + 1;
System.out.println(". The time of exit from unsync() method is "
+ System.currentTimeMillis());
}
}
class T1 extends Thread {
Stuff s;
public T1(Stuff s) {
this.s = s;
}
public void run() {
s.sync();
}
}
class T2 extends Thread {
Stuff s;
public T2(Stuff s) {
this.s = s;
}
public void run() {
s.unsync();
}
}
class Main {
public static void main(String args[]) throws Exception {
Stuff s = new Stuff();
T1 y = new T1(s);
T2 r = new T2(s);
y.start();
Thread.sleep(2000);
r.start();
}
}
The output of the program is below:
Okay, I am in sync() method. I will be waiting for 10 seconds. Current Time = 1358801766310
Alright, I am in unsync() method. The current time is 1358801768343. The time of exit from unsync() method is 1358801768343
Okay, I have waited for 10 seconds. Current time is 1358801776310. Now I will exit from sync() method, a = 11
Yes. Holding the monitor of an object prevents another thread from executing another block of code or synchronized on the same object. If a method is not synchronized, any thread can call it at any time, whether another thread holds a monitor or not.
Every access to a shared stated, even read-only accessed, must be synchronized if there's a chance that at least one thread modifies this shared state.
Is it that monitor in java does not restrict access to instance variables and only to the methods which are declared synchronized or code in synchronized statements?
Yes.
Synchronized blocks (or methods) are, among other things, mutually exclusive. That does not prevent the object used as a lock (the monitor, let's call it lock) to be used outside those blocks, in which case no synchronization will be performed. For example, one thread could read or write lock while another thread is within a synchronized block where lock is the monitor.
If you want to restrict access to a variable, you need to make sure that all accesses are made while holding a lock (any lock, provided it is the same for each access).
Making methods synchronized has two effects:
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
(source: the Java tutorials)

Two Synchronized blocks execution in Java

Why is it that two synchronized blocks can't be executed simultaneously by two different threads in Java.
EDIT
public class JavaApplication4 {
public static void main(String[] args) {
new JavaApplication4();
}
public JavaApplication4() {
Thread t1 = new Thread() {
#Override
public void run() {
if (Thread.currentThread().getName().equals("Thread-1")) {
test(Thread.currentThread().getName());
} else {
test1(Thread.currentThread().getName());
}
}
};
Thread t2 = new Thread(t1);
t2.start();
t1.start();
}
public synchronized void test(String msg) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
System.out.println(msg);
}
}
public synchronized void test1(String msg) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
System.out.println(msg + " from test1");
}
}
}
Your statement is false. Any number of synchronized blocks can execute in parallel as long as they don't contend for the same lock.
But if your question is about blocks contending for the same lock, then it is wrong to ask "why is it so" because that is the purpose of the whole concept. Programmers need a mutual exclusion mechanism and they get it from Java through synchronized.
Finally, you may be asking "Why would we ever need to mutually exclude code segments from executing in parallel". The answer to that would be that there are many data structures that only make sense when they are organized in a certain way and when a thread updates the structure, it necessarily does it part by part, so the structure is in a "broken" state while it's doing the update. If another thread were to come along at that point and try to read the structure, or even worse, update it on its own, the whole thing would fall apart.
EDIT
I saw your example and your comments and now it's obvious what is troubling you: the semantics of the synchronized modifier of a method. That means that the method will contend for a lock on this's monitor. All synchronized methods of the same object will contend for the same lock.
That is the whole concept of synchronization, if you are taking a lock on an object (or a class), none of the other threads can access any synchronized blocks.
Example
Class A{
public void method1()
{
synchronized(this)//Block 1 taking lock on Object
{
//do something
}
}
public void method2()
{
synchronized(this)//Block 2 taking lock on Object
{
//do something
}
}
}
If one thread of an Object enters any of the synchronized blocks, all others threads of the same object will have to wait for that thread to come out of the synchronized block to enter any of the synchronized blocks. If there are N number of such blocks, only one thread of the Object can access only one block at a time. Please note my emphasis on Threads of same Object. The concept will not apply if we are dealing with threads from different objects.
Let me also add that if you are taking a lock on class, the above concept will get expanded to any object of the class. So if instead of saying synchronized(this), I would have used synchronized(A.class), code will instruct JVM, that irrespective of the Object that thread belongs to, make it wait for other thread to finish the synchronized block execution.
Edit: Please understand that when you are taking a lock (by using synchronized keyword), you are not just taking lock on one block. You are taking lock on the object. That means you are telling JVM "hey, this thread is doing some critical work which might change the state of the object (or class), so don't let any other thread do any other critical work" . Critical work, here refers to all the code in synchronized blocks which take lock on that particular Object (or class), and not only in one synchronized block.
This is not absolutely true. If you are dealing with locks on different objects then multiple threads can execute those blocks.
synchronized(obj1){
//your code here
}
synchronized(obj2){
//your code here
}
In above case one thread can execute first and second can execute second block , the point is here threads are working with different locks.
Your statement is correct if threads are dealing with same lock.Every object is associated with only one lock in java if one thread has acquired the lock and executing then other thread has to wait until first thread release that lock.Lock can be acquired by synchronized block or method.
Two Threads can execute synchronized blocks simultaneously till the point they are not locking the same object.
In case the blocks are synchronized on different object... they can execute simultaneously.
synchronized(object1){
...
}
synchronized(object2){
...
}
EDIT:
Please reason the output for http://pastebin.com/tcJT009i
In your example when you are invoking synchronized methods the lock is acquired over the same object. Try creating two objects and see.

Inconsistent results with java threads

I have a thread class which implements runnable and an int counter as instance variable. Two synchronized methods add and sub. When I run my test class somehow it is printing wrong results once in couple of times. As far as I understand when a method is synchronized, entire object will be locked for accessing by other threads, with this logic every time we should get same results right? Some how that is not the case. Am I missing something?
My machine is Windows 7, 64 bit.
public class ThreadClass implements Runnable {
int counter = 0;
#Override
public void run() {
add();
sub();
}
public synchronized void add() {
System.out.println("ADD counter" + (counter = counter + 1));
}
public synchronized void sub() {
System.out.println("SUB counter" + (counter = counter - 1));
}
}
Testclass
public class ThreadTest {
public static void main(String args[]) {
ThreadClass tc = new ThreadClass();
Thread tc0 = new Thread(tc);
tc0.start();
tc0.setPriority(Thread.MAX_PRIORITY);
Thread tc1 = new Thread(tc);
tc1.start();
tc1.setPriority(Thread.NORM_PRIORITY);
Thread tc2 = new Thread(tc);
tc2.start();
tc2.setPriority(Thread.MIN_PRIORITY);
}
}
Results
ADD counter1
ADD counter2
SUB counter1
SUB counter0
ADD counter1
SUB counter0
Note: You may need to do couple of runs to produce this inconsistency.
Your results look correct.
During the execution of the methods, an exclusive lock on the object is obtained, but between the add() and sub() calls, the threads can freely interleave.
If you end up with a total of 0 after all the threads have run, then none of them overwrote eathother and the access to counter was synchronized.
If you wish to have counter only go from 0 to 1 sequentially and never hit 2, then do the following (which will render the method-level synchronization redundant so long as no other classes are involved):
#Override
public void run() {
synchronize(this) {
add();
sub();
}
}
However, this makes the whole point of the threads useless since you could do that in a single-threaded loop.
Synchronization will indeed mean that all threads will block waiting to acquire a lock before they can enter the synchronized block. Only one thread can ever have the lock on the object, so only one thread can be in the add() or sub() methods.
However, this does not imply anything else about the ordering of threads. You're starting three threads - the only guarantee is that they won't stomp on each other by running the add or sub methods at once. Thread 1 can call add(), then thread 3 can call add(), then thread 2 can call add(), then they can all call sub(). Or they could all call add() and then sub() each. Or any mixture - the only requirement being that each thread calls add() before it calls sub() and that no two threads will ever call add() or sub() while another thread is in that method.
Aside: it can be, in some cases, bad form to synchronize on this, as it's public - it's often preferred to use an internal private Object to lock on so that no other callers can take your lock and violate any locking strategies you have designed.
There is nothing wrong with either set of results. They are both perfectly consistent with what your code does. The running order of multiple threads is not guaranteed.
Your 'synchronized' methods ensure you get valid results -- each call to add in fact adds one and each call to sub in fact subtracts one. Without them, you could get a final result other than zero.

Categories