Synchronization works correctly in this code:
class PrintNumbers {
synchronized public void display() {
System.out.println("in display");
for (int i = 0; i < 3; i++) {
System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.getMessage();
}
}
System.out.println("out of display");
}
}
class MyThread implements Runnable {
Thread t;
PrintNumbers printNumbers;
MyThread(PrintNumbers printNumbers, String s) {
this.printNumbers = printNumbers;
t = new Thread(this,s);
t.start();
}
public void run() {
printNumbers.display();
}
}
class SyncExample {
public static void main(String[] args) {
PrintNumbers printNumbers = new PrintNumbers();
new MyThread(printNumbers, "My Thread 1");
new MyThread(printNumbers, "My Thread 2");
}
}
Output:
in display
Thread name : My Thread 1 i= 0
Thread name : My Thread 1 i= 1
Thread name : My Thread 1 i= 2
out of display
in display
Thread name : My Thread 2 i= 0
Thread name : My Thread 2 i= 1
Thread name : My Thread 2 i= 2
out of display
but not in this code:
class PrintNumbers {
synchronized public void display() {
System.out.println("in display");
for (int i = 0; i < 3; i++) {
System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.getMessage();
}
}
System.out.println("out of display");
}
}
class MyThread implements Runnable {
Thread t;
PrintNumbers printNumbers;
MyThread(String s) {
this.printNumbers = new PrintNumbers();
t = new Thread(this,s);
t.start();
}
public void run() {
printNumbers.display();
}
}
class SyncExample {
public static void main(String[] args) {
new MyThread("My Thread 1");
new MyThread("My Thread 2");
}
}
Output:
in display
Thread name : My Thread 1 i= 0
in display
Thread name : My Thread 2 i= 0
Thread name : My Thread 1 i= 1
Thread name : My Thread 2 i= 1
Thread name : My Thread 2 i= 2
Thread name : My Thread 1 i= 2
out of display
out of display
I cannot understand what difference wrt Synchronization does it make to initialize PrintNumbers in the Runnable MyThread and in the SyncExample class. Please explain.
I cannot understand what difference wrt Synchronization does it make to initialize PrintNumbers in the Runnable MyThread and in the SyncExample class.
It doesn't. What does matter is that in your first example, you have only one PrintNumbers instance which both threads share. But in your second example, you have two separate PrintNumbers instances, one for each thread.
Since PrintNumbers#display synchronizes on the instance (synchronized instance methods synchronize on this), it only synchronizes within the instance, not across multiple instances.
When both threads share an instance, the two calls to display are serialized. But when the threads each have their own instance, the two calls to display are on separate instances, and thus there is no serialization of the calls, they can overlap.
Because in the second code each thread has its own PrintNumbers object so they work in parallel. In the first one they share the single PrintNumbers object and work with it in synchronized way.
PS.
Remember that synchronized for non-static methods makes synchronization on object (for static methods on class).
It is working in both cases as it should. The difference is that in the first case you have a single object that is synchronized. In to second one you have two. They both are called only once so they are synchronized perfectly.
synchronized doesn't work between objects, only within one.
Related
This question already has answers here:
Java. The order of threads execution
(2 answers)
Closed 3 years ago.
Thread two is running first on output though I've called start() method of thread1 at first. Why this is happening?
Output:
Thread two running: 0
Thread two running: 1
Thread one running: 0
Thread two running: 2
....
package interfacetest;
class thread1 extends Thread {
public void run() {
for(int i=0; i<10; i++) {
System.out.println("Thread one running: " +i);
}
}
}
class thread2 extends Thread {
public void run() {
for(int j=0; j<10; j ++) {
System.out.println("Thread two running: " +j);
}
}
}
class InterfaceTest {
public static void main(String[] args) {
thread1 t1 = new thread1();
thread2 t2= new thread2();
t1.start();
t2.start();
}
}
When we start thread, java starts execution of run method in separate thread. And thread ordering is never gauranteed. Here as you are simply starting 2 different threads no gaurantee that they will be executed in sequence.
I am trying to print even and odd using two separate threads which communicate with each other by wait and notify.
I do know that i refers to Integer object which is in heap. hence changes made by one thread should be visible to both thread. Also I am using volatile keyword for declaration of Integet i.
I cant seem to understand how value of variable i is shown as 1 even after it has been incremented.
The output of code is
Even Thread got lock i=1
Even Thread waiting.. i=1
Odd Thread got lock i=1
Odd Thread : i=2
Odd Thread Run called NotifyAll
Odd Thread got lock i=2
Odd Thread waiting.. i=2
Even Thread woken up.. i=1
Even Thread waiting.. i=1
package programs;
public class EvenOdd {
static Object lck = new Object();
volatile static Integer i=1;
volatile static Integer N = 1000;
public static void main(String args[]){
EvenRunner e = new EvenRunner(lck, i, N);
OddRunner o = new OddRunner(lck, i, N);
Thread t1 = new Thread(e,"Even Thread ");
Thread t2 = new Thread(o,"Odd Thread ");
t1.start();
t2.start();
try {
t1.join();
t2.join();
}catch(InterruptedException ex) {
System.out.println("Interrupted : "+ex);
}
}
}
class EvenRunner implements Runnable{
Object lck;
Integer i;
Integer N;
EvenRunner(Object lck,Integer i,Integer N){
this.lck=lck;
this.i=i;
this.N=N;
}
#Override
public void run() {
while(i<N) {
synchronized(lck) {
System.out.println(" Even Thread got lock i="+i);
while(i%2==1){
try {
System.out.println(" Even Thread waiting.. i="+i);
lck.wait();
System.out.println(" Even Thread woken up.. i="+i);
}catch(InterruptedException e) {
System.out.println("Interrupted thread : "+e);
}
}
++i;
System.out.println(Thread.currentThread().getName()+" : i="+i);
System.out.println(" Even Thread Run called NotifyAll");
lck.notifyAll();
}
}
}
}
class OddRunner implements Runnable{
Object lck;
Integer i;
Integer N;
OddRunner(Object lck,Integer i,Integer N){
this.lck=lck;
this.i=i;
this.N=N;
}
#Override
public void run() {
while(i<N) {
synchronized(lck) {
System.out.println(" Odd Thread got lock i="+i);
while(i%2==0){
try {
System.out.println(" Odd Thread waiting.. i="+i);
lck.wait();
System.out.println(" Odd Thread woken up.. i="+i);
}catch(InterruptedException e) {
System.out.println("Interrupted thread : "+e);
}
}
++i;
System.out.println(Thread.currentThread().getName()+" : i="+i);
System.out.println(" Odd Thread Run called NotifyAll");
lck.notifyAll();
}
}
}
}
Expected Result: should be that other thread should also see the value of variable I as 2 after it has been incremented.
Actual result: value of variable i is read as 1 by other thread even after incrementing it.
Expected output should be that other thread should also see the value of variable I as 2 after it has been incremented.
When you construct evenRunner and oddRunner, you're copying the same Integer reference into each class as an instance field.
But Integer is immutable - when you execute ++i; that changes the field to refer to a different Integer object. It doesn't modify the content of the existing integer object... so your two threads are operating on entirely separate fields, and won't interact at all.
If you want to have a single object that both threads can modify, use AtomicInteger instead.
I just started learning "multithreading" in JAVA and it seams I don't understand how keyword "synchronized" works.
I had four examples and they're very alike (in my opinion), and I don't understand why I get every time different results.
public class BufferThread1 {
static int counter = 0;
static StringBuffer s = new StringBuffer();
public static void main(String args[]) throws InterruptedException {
new Thread() {
public void run() {
synchronized (s) {
while (BufferThread1.counter++ < 3) {
s.append("A");
System.out.print("> " + counter + " ");
System.out.println(s);
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(BufferThread1.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}.start();
Thread.sleep(100);
while (BufferThread1.counter++ < 6) {
System.out.print("< " + counter + " ");
s.append("B");
System.out.println(s);
}
}
}
Result:
run:
> 1 A
< 2 > 3 AA
AAB
< 5 AABB
< 6 AABBB
public class BufferThread2 {
static int counter = 0;
static StringBuilder s = new StringBuilder();
public static void main(String args[]) throws InterruptedException {
new Thread() {
public void run() {
synchronized (s) {
while (BufferThread2.counter++ < 3) {
s.append("A");
System.out.print("> " + counter + " ");
System.out.println(s);
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(BufferThread2.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}.start();
Thread.sleep(100);
while (BufferThread2.counter++ < 6) {
System.out.print("< " + counter + " ");
s.append("B");
System.out.println(s);
}
}
}
Result:
run:
> 1 A
< 2 AB
< 3 ABB
< 4 ABBB
< 5 ABBBB
< 6 ABBBBB
public class BufferThread3 {
static int counter = 0;
static StringBuffer s = new StringBuffer();
public static void main(String args[]) throws InterruptedException {
new Thread() {
public void run() {
synchronized (s) {
while (BufferThread3.counter++ < 3) {
s.append("A");
System.out.print("> " + counter + " ");
System.out.println(s);
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(BufferThread3.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}.start();
Thread.sleep(100);
synchronized (s) {
while (BufferThread3.counter++ < 6) {
System.out.print("< " + counter + " ");
s.append("B");
System.out.println(s);
}
}}
}
Result:
run:
> 1 A
> 2 AA
> 3 AAA
< 5 AAAB
< 6 AAABB
Of course, I skipped
import java.util.logging.Level;
import java.util.logging.Logger;
I just don't realise how these examples work and synchronized here !
I do hope that someone help me.
Your < and > label which thread is running here.
> 1 A
Your background thread is running only and prints this line as expected.
< 2
The main thread prints the counter 2 but cannot acquire the lock on s so it blocks.
> 3 AA
The background thread increments the counter again and prints 3 and a second A. On the next iteration it exits and counter == 4 As the thread exits, it releases the lock.
AAB
The main thread can now acquire the lock and append("B")
< 5 AABB
The main thread increments the counter to 5 and adds another B
StringBuffer is a pet hate of mine which was replaced more thna ten years ago by StringBuidler. It is almost impossible to implement a useful thread safe class using it and when people have tried, it has meant the class wasn't really thread safe. Note: SimpleDateFormat uses StringBuffer and it is not thread safe.
Let's try a simpler example that gets at what synchronized does without such an overly complicated class.
Consider the following Runnable task:
public class Task implements Runnable {
private final int id;
public Task(int id) {
this.id = id;
}
public void run() {
for(int i = 0; i < 5; i++) {
System.out.println("Task " + id + " prints " + i);
}
}
}
Then let's try running it with this main method:
public static void main(String[] args) {
Thread t1 = new Thread(new Task(1));
Thread t2 = new Thread(new Task(2));
t1.start();
t2.start();
}
The output could look something like this:
Task 1 prints 0
Task 1 prints 1
Task 1 prints 2
Task 1 prints 3
Task 1 prints 4
Task 2 prints 0
Task 2 prints 1
Task 2 prints 2
Task 2 prints 3
Task 2 prints 4
But it could also look like this:
Task 1 prints 0
Task 2 prints 0
Task 2 prints 1
Task 1 prints 1
Task 1 prints 2
Task 1 prints 3
Task 1 prints 4
Task 2 prints 2
Task 2 prints 3
Task 2 prints 4
Task 2 prints 4
The truth is, you have no guarantees about the order in which the two Tasks execute commands (with respect to each other. You still do know that each task will print 0...4 in order). The fact that t1.start() comes before t2.start() means nothing.
The synchronized command allows for some control over which thread executes when. Essentially, the command synchronized(obj) {....} means that at most one thread is allowed to execute the commands in the block (within the {...}) at a time. This is know as mutual exclusion.
A nice way to think about it is as a locked room with a single key hanging outside on the wall. In order to get into the room, you have to take the key off the wall, unlock the door, go into the room, and lock it from the inside. Once you are done doing whatever you are doing in the room, you unlock the door from the inside, go outside, lock the door from the outside, and hang the key up. It is clear that while you are in the room no one else can join you, as the door is locked and you currently hold the only key to get in.
To illustrate, consider the following improved task class:
public class SynchronizedTask implements Runnable {
private final Object lock;
private final int id;
public Task(int id, Object lock) {
this.id = id;
this.lock = lock;
}
public void run() {
synchronized(lock) {
for(int i = 0; i < 5; i++) {
System.out.println("Task " + id + " prints " + i);
}
}
}
}
And run it with the following modified main method:
public static void main(String[] args) {
Object lock = new Object();
Thread t1 = new Thread(new Task(1, lock));
Thread t2 = new Thread(new Task(2, lock));
t1.start();
t2.start();
}
We still don't know whether t1 or t2 will enter the synchronized block first. However, once has entered, the other must wait for it to finish. Thus, there are exactly two possible outputs of this code. Either t1 gets in first:
Task 1 prints 0
Task 1 prints 1
Task 1 prints 2
Task 1 prints 3
Task 1 prints 4
Task 2 prints 0
Task 2 prints 1
Task 2 prints 2
Task 2 prints 3
Task 2 prints 4
Or t2 gets in first:
Task 2 prints 0
Task 2 prints 1
Task 2 prints 2
Task 2 prints 3
Task 2 prints 4
Task 1 prints 0
Task 1 prints 1
Task 1 prints 2
Task 1 prints 3
Task 1 prints 4
It is important to note that this behavior only worked as desired because we used the same lock object for both Tasks. If we had run the following code instead:
public static void main(String[] args) {
Thread t1 = new Thread(new Task(1, new Object()));
Thread t2 = new Thread(new Task(2, new Object()));
t1.start();
t2.start();
}
We would have identical behavior to the original un-synchronized code. This is because we now have a room with two (or really, infinite if we replicate our thread initialization) keys hanging outside. Thus while t1 is inside the synchronized block, t2 can just use its own key to get in, defeating the whole purpose.
First example shown by Mr. Lawrey.
In the second example the "Background" thread only gets to do one print of and since StringBuilder is used this time instead of StringBuffer the main thread will not block while trying to print "s", hence only 1 A.
In the third example the main thread is blocked until the background thread terminates because you start the background thread before the main thread's loop. Thus the background thread will get 3 loops done and hence the 3 A's.
Though I suspect these are artificial examples for learning purposes it should still be noted that sleeping inside a synchronized block is NOT a good idea as this will not release the lock.
When I execute the following piece of code
public class ThreadTalk {
public static void main(String[] args) {
SimpleThread obj = new SimpleThread();
Thread t = new Thread(obj, "NewThread");
t.start();
synchronized (obj) {
System.out.println("In Synchronized BLOCK");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Out of Synchronized BLOCK");
}
}
}
class SimpleThread implements Runnable {
public void run() {
System.out.println("The thread running now " + Thread.currentThread());
for (int i = 0; i < 10; i++) {
System.out.println("The val of i= " + i);
}
}
}
The output that I am getting is
In Synchronized BLOCK
The thread running now Thread[NewThread,5,main]
The val of i= 0
The val of i= 1
The val of i= 2
The val of i= 3
The val of i= 4
The val of i= 5
The val of i= 6
The val of i= 7
The val of i= 8
The val of i= 9
Out of Synchronized BLOCK
where as I am expecting an output like
In Synchronized BLOCK
Out of Synchronized BLOCK
The thread running now Thread[NewThread,5,main]
The val of i= 0
The val of i= 1
The val of i= 2
The val of i= 3
The val of i= 4
The val of i= 5
The val of i= 6
The val of i= 7
The val of i= 8
The val of i= 9
If I am putting a Lock on the SimpleThread object using the Synchronized block of main thread, how is my NewThread running when main thread is going to sleep.I mean shouldn't the NewThread wait till the Main thread has removed the lock on the SimpleThread object, as both threads are running on the same object.
run() and/or start() do not take any locks. They just run code. You need to actually have SimpleTread take the same lock as the main thread for those two threads to synchronize in some fashion.
Rather than try to synchronize on the the Runnable object, I think best practice would be to explicitly declare a separate object to use as a lock.
class ThreadTalk{
public static void main(String[] args){
Object lock = new Object();
SimpleThread obj=new SimpleThread( lock );
Thread t=new Thread(obj,"NewThread");
t.start();
synchronized(lock){
System.out.println("In Synchronized BLOCK");
try{
Thread.sleep(5000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Out of Synchronized BLOCK");
}
}
}
class SimpleThread implements Runnable{
private final Object lock;
public SimpleThread( Object lock ) { this.lock = lock;}
public void run(){
synchronized( lock ) {
System.out.println("The thread running now "+Thread.currentThread());
for(int i=0;i<10;i++){
System.out.println("The val of i= "+i);
}
}
}
}
synchronized block does not do what you think. It means that only one thread can be inside of it (or rather inside any synchronized block on the same object) at the same time. In your case, there is only one (main) thread inside the block. The other one is executing different code. That is expected.
You need to synchronize in both threads on the same object (the so-called "monitor") to make them mutually exclusive.
The simplest way to do that is to make the run() method itself synchronized:
class SimpleThread implements Runnable {
// See the synchronized modifier on the next line
public synchronized void run() {
System.out.println("The thread running now " + Thread.currentThread());
for (int i = 0; i < 10; i++) {
System.out.println("The val of i= " + i);
}
}
}
You would also need to make sure that you synchronize on the SimpleThread object before you start it in a Thread, so you need to move the t.start(); statement inside the synchronized (obj) { block. If you don't do that, the two threads are still improperly synchronized, and there's no telling which thread will run first.
I have a requirement in which 28 threads have to complete some functionality. I have created these threads as in anonymous inner classes like :
Thread t=new Thread(new Runnable(){public void run()
{//code
}}
);
t.start();
Now I want that the further execution should start after all these threads have finished there work.
Note : I am confused about join() method as it makes my threads run sequentially.
So can anyone suggest me how can I make main thread run once these threads are done with work.
Note : I am confused about join() method as it makes my threads run sequentially.
It will do that if you have code like this:
for (Runnable runnable : runnables) {
Thread t = new Thread(runnable);
t.start();
t.join();
}
However, you can start all the threads you want to run in parallel, then call join on them all. For example:
List<Thread> threads = new ArrayList<>();
for (Runnable runnable : runnables) {
Thread t = new Thread(runnable);
t.start();
threads.add(t);
}
// Now everything's running - join all the threads
for (Thread thread : threads) {
thread.join();
}
// Now you can do whatever you need to after all the
// threads have finished.
There are many other approaches, of course - starting threads directly may well not be as suitable in your code as using a higher level abstraction; it depends on what you're trying to achieve. The above should work fine though - assuming all the Runnables are able to run in parallel without blocking each other through synchronization.
Make use of CountDownLatch.
public static void main(String... args) {
final CountDownLatch latch = new CountDownLatch(28);
for(int i=0;i<28;i++) {
Thread t=new Thread(new Runnable(){
public void run()
{
try {
//code
} finally {
latch.countDown();
}
}
});
t.start();
}
latch.await();
// Continue Code
}
Use a CountDownLatch and wait for all your threads to complete. :) .
PS : I gotto agree, using join() is also correct and more efficient.
example code :
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("t1 : " + i);
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("t2 : " + i);
}
}
});
t2.start();
t1.join();
t2.join();
System.out.println("main");
}
O/P :
t1 : 0
t1 : 1
t2 : 0
t1 : 2
t1 : 3
t2 : 1
t1 : 4
t1 : 5
t2 : 2
t1 : 6
t1 : 7
t2 : 3
t1 : 8
t1 : 9
t2 : 4
t2 : 5
t2 : 6
t2 : 7
t2 : 8
t2 : 9
main
According to the behaviour you're giving for join, I'm guessing you're starting and joining the threads within a single loop.
If you check the javadoc on this page, you'll note that a call to join will halt the execution of the calling thread until the other thread has finished executing.
You might want to keep an array or a list of threads when creating them, and starting them all in one loop, and only then joining them all.
Thread[] workers = new Thread[28];
for (int i = 0; i < workers.length; i++) {
workers[i] = new Thread { ... };
}
// Start running all threads
for (Thread worker: workers) {
worker.start();
}
// Make sure all threads are completed
for (Thread worker: workers) {
worker.join(); // if the worker already stopped, it'll return immediately.
}
// Now all threads have finished running and you can start post-processing
It's not the most elegant solution, but it'll do the trick.
As mentioned by others, you should probably use a CountDownLatch (haven't used one yet, so I can't provide feedback)
Edit: I've been beaten to it by Jon Skeet, sorry for the redundant answer...
CountDownLatch is better option.
I have created dummy program.
In this program I am sum 1000 number. I created 10 thread. In main thread I am doing dome of all child thread sum. you will get understand to simply viewing the code.
package Test1;
import java.util.concurrent.CountDownLatch;
class Sum extends Thread {
private int from;
private int to;
private int sum = 0;
CountDownLatch latch;
public int getSum() {
return sum;
}
public Sum(int from, int to, CountDownLatch latch) {
this.from = from;
this.to = to;
this.latch = latch;
}
public void run() {
for (int i = from; i < to; i++) {
sum += i;
}
latch.countDown();
}
}
public class Test5 {
public static void main(String[] args) throws InterruptedException {
int n = 1000;
int tn = 10;
int from = 1;
int to;
int sum = 0;
Sum[] sumArray = new Sum[tn];
final CountDownLatch latch = new CountDownLatch(tn);
for (int i = 0; i < tn; i++) {
to = from + n / tn;
Sum s = new Sum(from, to, latch);
sumArray[i] = s;
s.start();
from = to;
}
// Thread.sleep(1000);
latch.await();
for (int i = 0; i < tn; i++) {
sum += sumArray[i].getSum();
}
System.out.println(sum);
}
}