I am trying to understand synchronization in JAVA. I have written a small program.
class A implements Runnable {
public void run() {
Random r = new Random();
int i = r.nextInt(10);
if(i<5){
print();
}else{
display();
}
}
public synchronized void display()
{
System.out.println("display");
print(); // Line no: 19
}
public synchronized void print()
{
System.out.println("print");
}
}
public class Test {
public static void main(String argv[]) throws Exception {
A a = new A();
Thread t = new Thread(a, "A");
Thread t1 = new Thread(a, "B");
t.start();
t1.start();
}
}
Consider 1st case: I have put a debug point on the 1st line inside print method.
Now when thread A starts running and number randomly generated number 1.
It will call print method and as I have debug point on its first line. It will wait for me to resume.
Now during that time, thread B starts running and number randomly generated number 8.
It should call display method but I see the execution doesn't go inside the display method. It will go inside only after I have make sure that thread A has finished execution.
Shouldn't thread B should go inside display method and wait on the line no 19.
Can two thread generated by same object cannot execute 2 different synchronized method?
Please explain.
To enter a synchronized method of an object, the thread must acquire the intrinsic lock associated with that object. The lock is bound to the object. Each method doesn't have its own lock.
Since thread A is inside a synchronized method of your Runnable, the other thread must wait for the lock to be released before being able to enter a synchronized method, whether the method is the same or not.
Related
Why I'm not able to achieve Synchronization on this below piece of program:
class P
{
synchronized void pp(String s)
{
System.out.println (s);
}
}
class threadA extends Thread
{
P ob;
String s;
threadA (P ob, String s)
{
this.ob = ob;
this.s = s;
}
public void run ()
{
for (int i=1;i<=5;++i)
{
ob.pp (s);
try
{
Thread.sleep (1000);
}
catch (Exception e) {}
}
}
}
class gain
{
public static void main(String[] args) {
P ob = new P ();
threadA a = new threadA (ob,"Hello User");
threadA b = new threadA (ob,"Bye User");
a.start();
b.start();
}
}
OP:
Hello User
Bye User
Hello User
Bye User
Bye User
...
I want OP in the form of:
Hello User
Hello User
Hello User..
Bye User
Bye User
Bye User..
or my concept of synchronization is wrong?
You cannot do such synchronization from P class. What happens now is that any calls to pp() is blocked if another thread is currently executing the method. As long as the method ends (which is quick if you are just going to print things to the console), the next thread would be allowed to enter the method.
What you are trying to achieve is not possible, unless both the threads are aware of each other and communicate with each other. In other words, when the first thread finishes what it needs to do, it should explicitly inform the second thread to start. This is effectively executing sequentially, instead of parallelly.
Update
You wanted to visualize what is happening so I'll do it here.
You created 2 threads.
You start the first thread.
The first thread starts to run, while some time later the second starts to run as well.
When your first thread runs, it goes to the for loop. Then it calls P.pp().
When P.pp() is called from first thread, it locks the P object.
Since the method is so short, it is going to exit very quickly.
When the method exits, it releases the lock on P.
If your second thread reaches the synchronize block before the first thread exits, it will wait (blocked).
When the first thread exits, the second thread enters as the first thread releases the lock.
The first thread returns to the loop and try to call P.pp() again.
This will continue, depending on which thread is faster, the order of execution would be different.
Synchronized keyword means that two threads on that code block have to respect the order they tried to access that block code. It doesn't mean that the execution flow is serialized.
To have what you want try to put the for inside the synchronized block...
You should try something like this
class P
{
void pp(String s)
{
System.out.println (s);
}
}
class threadA extends Thread
{
P ob;
String s;
threadA (P ob, String s)
{
this.ob = ob;
this.s = s;
}
public void run ()
{
for (int i=1;i<=5;++i)
{
synchronized(ob)
{
ob.pp (s);
try
{
Thread.sleep (10);
}
catch (Exception e) {}
}
}
}
}
public class gain
{
public static void main(String[] args) {
P ob = new P ();
threadA a = new threadA (ob,"Hello User");
threadA b = new threadA (ob,"Bye User");
a.start();
b.start();
}
}
i.e while sleeping keep thread synchronized so that you get required output or else you are not sure which thread might come up first after sleep. See this
can u explain me the flow of control of my program?
"Hello" starts and run through the loop until it reaches the synchronized method
"Bye" does the same.
"Hello" is the first to acquire the lock.
"Bye" blocks waiting for the lock.
"Hello" executes the method and releases the lock.
"Bye" can now acquire the lock and "Hello" has released it
"Bye" can now execute the method, and releases the lock as "Hello" did.
what can I do so that hello after executing the method goes to blocked pool and also doesn't leaves the lock for bye to acquire it
Hold the lock, and don't release it if you want to retain it.
public void run() {
synchronized(ob); { // hold the lock the whole time
for (int i = 1; i <= 5; ++i) {
ob.pp (s);
try { Thread.sleep(1000); } catch (Exception e) {}
}
} // releases the lock here.
}
Below is my sample code, when my a.start() called it should create a thread and print "Run" immediately. But why does is called after printing "begin" 20 times.
How does thread "a" decide that it doesn't have to call run() immediately.
public class JoinTest implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new JoinTest());
a.start();
for (int i = 0; i < 20; i++) {
System.out.print("Begin");
}
Thread.sleep(1000);
a.join();
System.out.print("\nEnd");
}
public void run() {
System.out.print("\nRun");
}
}
Output:
BeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBegin
Run
End
I am little confused about the behavior of thread.
In my opinion "run" should be printed before "begin" because it get printed before the join() method is called, and at the time of join method called thread "a" must have finished its execution and calling join must be useless at that point.
Calling start() on a thread doesn't necessarily triggers the execution of its run() method immediately. Your thread is marked as started but the main thread pursues its execution into the for loop. Then the JVM is switching to your thread once the main thread reaches the sleep() statement.
You start the thread, then immediately do some printing, then sleep. Looking at your code I would actually expect to see Begin before Run because the thread is being started in the background, concurrently to your main thread going on with its work. Futhermore, the print method is synchronized so you repeatedly acquire that lock in a loop, giving even less chance to the second thread to interject.
I have tried your code with Thread.sleep eliminated, both with and without the join call. The behavior is the same in both cases: Run comes at the end most of the time and occasionally manages to get interleaved between the Begin words. Everything exactly as expected by the simple model of concurrency with synchronized blocks.
Here is a slight variation on your code which reliably prints Run before everything else, whether you call the join method or not. All that changed is the position of the sleep call.
public class JoinTest implements Runnable
{
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new JoinTest());
a.start();
Thread.sleep(1000);
for (int i = 0; i < 20; i++) {
System.out.print("Begin");
}
a.join();
System.out.print("\nEnd");
}
public void run() {
System.out.print("\nRun");
}
}
The start() method calls the thread's run() method, although this takes a little time, which may just be enough for some or all of your 'Begin' loops to complete. When I run this on my machine the 'Run' output appears between the first and second 'Begin'. Try outputting with timestamps so you can see how long your machine is taking to execute each command:
public class JoinTest implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new JoinTest());
a.start();
for (int i = 0; i < 20; i++) {
System.out.println("Begin " + System.nanoTime());
}
Thread.sleep(1000);
a.join();
System.out.println("End " + System.nanoTime());
}
public void run() {
System.out.println("Run " + System.nanoTime());
}
}
Calling a.join() at that point ensures that you will always see 'Run' output before 'End', as join() waits for the thread to complete.
I have tried many scenarios with join(), "run" always get printed after "begin" but when i remove the join statement "run" always get printed before "begin". Why?
Because it's allowed. That's why. As soon as you call .start(), you have two threads. Untill your program calls a synchronization methods like .join() it's entirely up to the JVM implementation and the operating system to decide which thread gets to run when.
The a.join() call from your main thread forces the main thread to wait until the a thread has completed its run() method.
Without the a.join() call, the Java Language Specification permits the a thread to complete its work before a.start() returns in the main thread, and it permits the main thread to reach the end of the main() function before the a thread even begins to run, and it permits anything in between to happen.
It's entirely up to the JVM and the OS.
If you want to take control of the order in which things happen, then you have to use synchronized blocks, and synchronization objects and method (e.g., .join()).
But beware! The more you force things to happen in any particular order, the less benefit your program will get from using threads. It's best to design your program so that the threads can function independently of one another most of the time.
I have a portion of code dealing with threads and I want to understand its function in detail. The run method is empty in my example, but lets assume it has some operations to do on a global variable:
import java.io.File;
public class DigestThread extends Thread {
private File input;
public DigestThread(File input) {
this.input = input;
}
public void run() {
}
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
File f = new File(args[i]);
Thread t = new DigestThread(f);
t.start();
}
}
}
After creating a thread and starting it, will it wait to finish the tasks in the run method before creating/running another thread ?
second question
if a variable has declared in run method that means it will be declared many times because every thread created will do the task in run method , is every thread handles its own varible although variable in each thread are same ?
will it waitng for finish the tasks in run method to creat another
method ?
No. That's the whole point of Multithreading. Every thread has it's own stack of execution. So, when you start a thread, it enters the run() method, and executes it in a different stack, and at the same time the main thread continues execution, in it's own stack.
After that, main thread, can spawn another thread. Thus all the threads run simultaneously, but of course, one at a time, sharing the CPU amongst them, based on the specific CPU allocation algorithm being used.
It's not possible to write down all the details about the execution process of multiple threads here. I would rather suggest to read some tutorials or search for some online resources, regarding the concept of Multithreading. Once clear in concept, move ahead with the implementation in Java.
Here's some tutorials links you can start with: -
Thread Wiki Page
SO Multithreading Wiki Page
Concurrency - Oracle Tutorial
http://www.vogella.com/articles/JavaConcurrency/article.html
Once you start a thread, it will run in a separate thread and the main() thread will continue (it may end before the child thread ends).
If you want the thread to finish before main then you can use the Thread.join method on thread to wait for it.
First, Thread is a single sequential flow of control within a program.
We can execute more than one thread in a program, but there is a life cycle, where you can find out how threads work...
Whenever we call the start() method of Thread it automatically calls the overriden method public void run() and executes the code of the run() method...
Here is a simple example of Thread in Java with ABC and XYZ thread classes
/* Write a program to print having two Thread Class 1) ABC with 1 second 2) XYZ 2 second. 10 times with Extend Constructor */
class ABCThreadConstructor extends Thread {
ABCThreadConstructor(String name) {
super(name);
}
public void run() {
try {
for(int i = 0; i < 10; i++) {
System.out.println("ABC");
Thread.sleep(1000);
}
} catch(InterruptedException ie) {
System.out.println("Interrupted Exception : "+ie);
}
}
}
class XYZThreadConstructor extends Thread {
XYZThreadConstructor(String name) {
super(name);
}
public void run() {
try{
for(int i = 0; i < 10; i++) {
System.out.println("XYZ");
Thread.sleep(2000);
}
} catch(InterruptedException ie) {
System.out.println("Interrupted Exception : "+ie);
}
}
}
class AbcXyzThreadConstructorDemo {
public static void main(String args[]) {
ABCThreadConstructor atc = new ABCThreadConstructor("ABCThreadConstructor");
System.out.println("Thread Name : " + atc.getName());
atc.start();
XYZThreadConstructor xtc = new XYZThreadConstructor("XYZThreadConstructor");
System.out.println("Thread Name : " + xtc.getName());
xtc.start();
}
}
Assuming your question is "After creating a thread and starting it, will the program wait for the thread to finish its run method before creating another thread?"
If that's the case, No the program will not wait. t.start() kicks off the thread and it gets its own chunk of memory and thread priority to run. It will do its operations and then exist accordingly. Your main thread will start the number of threads specified in args before terminating.
If you need the application to wait on the thread then use t.join(). That way the parent thread (the one that runs main) will be joined to the child thread and block until its operation is complete. In this case it sort of defeats the purpose of threading but you can store the thread ID for whatever logic you need and join() later.
As we know there is no provision to prevent more than one thread calling the run() method by using start() method. I did create two objects m1 and m2 both calling the same thread to run.
I need to make sure the first object finishes (m1.start) its execution by calling thread before second object execution starts.
My question is why can't i use synchronized keyword with run() method in the thread that I have created (i.e. MyThread1)?
I tried using "synchronized" to run() method in the thread that I have created but it gives arbitrary output (in other words m2 doesn't wait for the m1 to finish execution).
You can see at the very bottom of the program the output that I am getting.
public class ExtendedThreadDemo {
public static void main(String[] args) {
Mythread1 m1 =new Mythread1();
Mythread1 m2 =new Mythread1();
m1.start();
m2.start();
System.out.println(" main thread exiting ....");
}
}
MyThread
public class MyThread1 extends Thread {
public synchronized void run() {
for(int i=1; i<5; i++) {
System.out.println(" inside the mythread-1 i = "+ i);
System.out.println(" finish ");
if (i%2 == 0) {
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
System.out.println(" the thread has been interrupted ");
}
}
}
}
}
Output
main thread exiting ....
inside the mythread-1 i = 1
finish
inside the mythread-1 i = 2
finish
inside the mythread-1 i = 1
finish
inside the mythread-1 i = 2
finish
inside the mythread-1 i = 3
finish
inside the mythread-1 i = 4
finish
inside the mythread-1 i = 3
finish
inside the mythread-1 i = 4
finish
As you can see after i = 2, second object (i.e. m2.start()) started executing.
Call m1.join() in main before calling m2.start().
Making methods synchronized only affects multiple calls to methods on the same object; m1 and m2 are different objects, so adding synchronized will have no effect.
This code snippet:
public synchronized void run() {
//code
}
is semantically equivalent to:
public void run() {
synchronized(this) {
//code
}
}
Note the this reference. This means that all synchronized blocks using the same this reference (lock object) are mutually exclusive. However you are creating two threads (objects), each is synchronizing on a different this reference.
There are several ways to improve your code:
Use only one Runnable and create two threads:
public class Mythread1 implements Runnable //...
and then:
Runnable r = new Mythread1();
Thread m1 = new Thread(r);
Mythread1 m2 = new Thread(r);
But this will only work if Mythread1 runnable is statelss as it will be shared by two threads.
Use the same lock instance
Pass some arbitrary lock object to both instances of Mythread1 and then use:
synchronized(lock) {
//code
}
Starting from Java 5 there are much more sophisticated ways of synchronizing code, but this one is fine for simple cases.
Use Thread.join()
You can call:
m1.start();
m1.join();
m2.start();
This will do the trick.
A synchronized instance method only hinder concurrent access to the same instance of the class. You would see your expected effect if the run method was static. But I do not suggest making the run method static. In fact you cannot if it is to keep its current functionality. What you should instead consider is using m1.join() to wait for m1 to finish. Another approach which works better if you have multiple threads which are to wait for each other is to use a CyclicBarrier or a CountDownLatch.
I'm learning how to work with threads in Java and I need some advice..
I want to print on the standard output numbers from 0..50 with the name of the thread that has done it using three threads.
I have two classes - class Counter that implements Runnable and class Main that creates and runs the threads. Counter has the variable c which is shared among the threads.
My idea was, that I increment c by 1 and then call yield() on the current thread so as the other threads would do the same. Repeat this until c reaches 50.
But it doesen't work, the numbers are printed out in wrong order. How do I fix this?
public class Counter implements Runnable {
Thread t1;
private int c = -1;
public Counter() {
}
public Counter(String name) {
t1 = new Thread(this, name);
t1.start();
}
#Override
public void run() {
while (c < 50) {
increment();
Thread.yield();
}
}
public void increment() {
if (c < 50) {
c++;
System.out.println(Thread.currentThread().getName() + ": " + c);
}
}
}
public class Main {
public static void main(String[] args) throws IllegalThreadStateException {
Counter c1 = new Counter();
Thread t1 = new Thread(c1, "Thread 1");
Thread t2 = new Thread(c1, "Thread 2");
Thread t3 = new Thread(c1, "Thread 3");
t1.start();
t2.start();
t3.start();
}
Edit: In the end I solved it this way. Thank you all who helped me with the tough start with multithreading.
import java.util.concurrent.atomic.AtomicInteger;
public class Counter2 implements Runnable {
// you could also use simple int
private AtomicInteger c = new AtomicInteger(-1);
private static final Object syncObject = new Object();
public Counter2() {
}
#Override
public void run() {
while (c.get() < 50) {
synchronized (syncObject) {
if (c.get() < 50) {
System.out.println(Thread.currentThread().getName() + ": " + c.incrementAndGet());
}
}
}
}
}
Use syncrhonized section in method increment with special static object.
private static final Object syncObj = new Object();
public void increment()
{
syncrhonized( syncObj )
{
c++;
System.out.println(c);
}
}
Or make this method synchronized via its declaration.
But it's wrong idea to store your real data in thread objects. Thread should just to manipulate with share objects but not to store them.\
And actually I don't understand why do you start thread in
Quoting from the javadoc Thread.yield(), emphasis by me:
public static void yield()
A hint to the scheduler that the
current thread is willing to yield its
current use of a processor. The
scheduler is free to ignore this
hint.
...
It is rarely appropriate to use
this method.
Make increment() synchronized in order to prevent other threads from entering the method concurrently.
In conjunction with yield() you should be able to get another thread print the next number (not always since the system might resume the thread that called yield again - see Ingo's answer - , but the order should still be the same).
synchronized increment() would mean that any thread that tries to enter that method on the same object would have to wait if another thread would have aquired the lock already by entering the method.
Yes your code won't work. Thread#yield() won't control the thread scheduler in the manner you desire. I"m curious what result you get. You'll probably get repeated numbers and some number that are slightly out of order.
You could use atomic integer which should remove all duplicates. But since the print statement is not atomic. You may still print your results out of order. So you should probably just synchronize the increment method. Also you don't really need yield so dump it.
If the purpose of the problem is to go from thread 1 to thread 2 to thread 3 back to thread 1, etc... Such that the results are
Thread 1:0
Thread 2:1
Thread 3:2
Thread 1:3
Thread 2:4
Thread 3:5
Thread 1:6
Thread 2:7
....
Then you'll need to lock the increment method and use wait and notifyAll. wait will cause other threads to halt processing until the current thread notifies them to start again.