Can we use synchronised for run() method in java? - java

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.

Related

Java using wait/notify methods on threads that do same thing

I was trying to understand the monitor on Java and the question that came to me is how to make the threads that run the same synchronized method to wait?
I was trying to make a simple program that would make 3 threads to use the same method to add to N element 1 for total of 10 000 times and I was wondering how to make other threads to wait when one is doing adding method and notifyAll after it is done if I would start all of them at the same time.
Here is my program that I wrote without wait/notify functions :
class Swapper implements Runnable{
int number;
Swapper(int number){
this.number=number;
}
#Override
public void run() {
while (mainClass.counter>0){
mainClass.incArrayElement(number);
}
}
}
public class mainClass {
public static volatile int counter = 10000;
public static volatile int[] testArray = new int[]{0,0,0};
public static synchronized void incArrayElement(int index){
if (counter>0) {
testArray[index - 1]++;
counter--;
}
else {
return;
}
}
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new Swapper(1));
Thread thread2 = new Thread(new Swapper(2));
Thread thread3 = new Thread(new Swapper(3));
thread1.start();
thread2.start();
thread3.start();
thread1.join();
thread2.join();
thread3.join();
int checkSum = 0;
for (int i = 0; i < testArray.length; i++) {
System.out.println(testArray[i]);
checkSum+=testArray[i];
}
System.out.println(checkSum);
}
}
When a thread calls the synchronized method 'incArrayElement' of your class it acquires the lock of that object, any new thread cannot call ANY synchronized method of the same object as long as previous thread which had acquired the lock does not release the lock. Hence all other threads will be blocked until the execution is complete.
So why do you need to have the threads to call wait() as they are blocked already and waiting.
Unfortunately your example is not well chosen.
The method declared synchronized is controlled in a way that other threads cannot call it unless it has finished execution. Then one of the threads calls this method again. 'Which thread' cannot really be told because you have no control over it. Using wait and notify functions will not give you control over this neither. So if that is what you are looking for, you cannot achieve what you want. It will remain indeterministic for you.
If simply assuring that the method is called by only one thread at a time, then you already have that behavior, no need for wait or notify.

Why second thread not going inside `display()` method?

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.

Using threads in Java

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.

Compiler logic with Java Multithreading?

So I'm slightly confused as to how multi-threading works. For example, if I create a subclass of Thread called MySub, and this is what it looks like:
public class MySub extends Thread {
public void run {
for(int i = 0; i < 5; i++){
System.out.println(i);
}
}
}
And in the main class I do this:
public static void main(String[] args) {
Thread m = new MySub();
Thread m2 = new MySub();
m.start();
m2.start();
}
Shouldn't it call the start() method for m, and then go straight to calling the start() method for m2, without waiting for the m thread to finish? Isn't that the point of multithreading?
But in actuality, it prints 0 through 4 from the start() call for m, and then 0 through 4 for the start() call for m2. They didn't go concurrently, they went sequentially, which isn't what I expected. I kind of expected a mess of 0 through 4 numbers.
This is a race condition #Jake. Your main is not waiting for the first thread to finish before starting the second. It is starting the first thread which finishes its work before main gets a chance to start the second thread.
If you tried printing (let's say) 1000 numbers or something that takes more time, you would start to see them interleave. Or you could put a Thread.sleep(10) between your println statements which would show it more specifically.
FYI: it is recommended to have your classes implement Runnable as opposed to extends Thread. Then you would do:
Thread m1 = new Thread(new MySub());
m1.start();
Also, use of the ExecutorService code is recommended more than using thread directly.

Java Thread synchronization - printing out numbers in right order

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.

Categories