Here is my following code:
private int counter = 0;
public void incC() {
counter++;
System.out.println("Counter is: "+counter + " "+Thread.currentThread().getName());
}
public void printC() {
System.out.println("Counter is: "+counter + " "+Thread.currentThread().getName());
}
public static void main(String args[]) throws Exception {
Stuff stuff = new Stuff();
Thread t1 = new Thread(() -> {
stuff.incC();
});
Thread t2 = new Thread(() -> {
stuff.printC();
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
Here's my output:
Counter is: 1 Thread-1
Counter is: 1 Thread-0
Here t1.join() is called first. So shouldn't thread t2 should wait for thread t1 to die?
How's it possible for thread t2 to output first before t1?
t1.join() makes the current thread wait for thread t1 to die. It has no effects on the timing of any other thread but the current one. You have started two threads and they will run concurrently with no ordering constraints.
I should also note that starting two threads only to have one wait for the other's death defeats the purpose of multithreading.
join() forces to wait current (in your case the main) thread to death of t1, so t2 continues to work
Order for thread execution is not fixed because they work in parallel
Both threads works in parallel and therefore no guarantee on which thread will finish first in your case.
If you want a specific thread to finish first you have to start it and join it with your main thread then start and join the second thread like follows.
t1.start();
t1.join();
t2.start();
t2.join();
Set names for the threads for better understanding.
Also change your question because your threads are working fine.
Related
Consider this code:
public class print extends Thread {
public void run() {
Out.print("Hello");
Out.println("World");
}
}
public class test {
public static void main (String[] args) {
Thread t1 = new print();
Thread t2 = new print();
Thread t3 = new print();
Thread t4 = new print();
Thread t5 = new print();
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
try {
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
}catch(InterruptedException e) {
}
}
}
The goal is to print out hello, than world in the next line.The output isn't right,and it is very inconsistent, meaning every few test it changes.I've never worked with threads,but I did some reaserch and it says that using this .join should wait for one thread to finish so that the next one starts. What am I doing wrong?
Thank you!
and it says that using this .join should wait for one thread to finish so that the next one starts
That is not what join does.
join blocks the current thread until the target thread is finished. It does not do anything about any other threads.
In your case, the main thread will wait for t1 to finish, then for t2 and so on. But it does nothing to schedule how t1 runs in relation to t2. In particular, it also does not delay starting t2. t2 starts when you said t2.start().
Okay,so how do I tell the others to wait as well?
Ideally you use higher level constructs like work queues and executor services instead of messing with low-level threading primitives.
If you do want to continue doing that, look at ReentrantLock or CountDownLatch. Or have t1 call t2.join().
I would probably use a CountDownLatch. Set up the latch to require five tickets, then each of your threads can print the first line, then block at the latch, and only when the latch releases (which happens when all five have arrived), they will continue to print the second line.
Also note that if you want to run these tasks in a sequence one after the other, you do not need multiple threads at all. Just do t1.run(); t2.run(); t3.run(); on the same thread.
I have read daemon threads are low priority threads and it runs only when no other user threads are alive. But the below code does not have any difference.
public class DaemonThreadTest {
public static void main(String[] args) {
DaemonThread d = new DaemonThread();
Thread t1 = new Thread(d,"daemon");
t1.setDaemon(true);
Thread t2 = new Thread(d,"Non-Daemon");
t1.start();
t2.start();
System.out.println("Main finished");
}}
class DaemonThread implements Runnable{
public void run(){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+ i);
}
}}
And the output is,
Main finished
Non-Daemon0
Non-Daemon1
Non-Daemon2
Non-Daemon3
Non-Daemon4
Non-Daemon5
Non-Daemon6
Non-Daemon7
daemon0
daemon1
daemon2
daemon3
daemon4
daemon5
daemon6
daemon7
daemon8
daemon9
Non-Daemon8
Non-Daemon9
Threading priorities are largely handled by the operating system and so it plays a big part in deciding when to allow Threads to run. For example I ran your code a couple of times and on one run I got this output:
Main finished
daemon0
daemon1
daemon2
daemon3
daemon4
daemon5
daemon6
daemon7
daemon8
daemon9
Non-Daemon0
Non-Daemon1
Non-Daemon2
Non-Daemon3
Non-Daemon4
Non-Daemon5
Non-Daemon6
Non-Daemon7
Non-Daemon8
Non-Daemon9
Which is almost a complete reverse to your results. Whilst you can try setting priorities manually it will still ultimately come down to how the operating system runs your threads.
Regarding Daemon threads, a daemon is like a 'sub-thread' (or child thread as I like to think :) ) of a user thread. This means it is linked/connected to a user Thread. In your case it is linked to the main thread, when the main thread ends the daemon will die with it. HOWEVER because you have another user Thread running (t2) the main method waits until that is finished. If you were to comment out t2 like so:
// Thread t2 = new Thread(d,"Non-Daemon");
t1.start();
// t2.start();
and then run your program you would likely find the daemon thread never runs because main ends too soon and when it exits takes the daemon thread with it.
Priority Check
Change your loop code statement to this:
System.out.println(Thread.currentThread().getName()+ i
+ " [Proirity] " + Thread.currentThread().getPriority());
And you can see the priority for yourself. Priority is scaled from 1 -10, when I ran it both t1 and t2 had priority 5 so netiher was lower than the other.
I'm playing with threads in Java and i have a question about the join() method.
Let's say i have a SampleClass that extends Thread. I instantiate some new threads in the main but i want the thread's job to be completed sequentially using join().
public static void main(String[] args) {
for(int i=0; i<5; i++){
new SampleClass().start();
}
}
Is it possible to call immediately join()? ...something like this:
new SampleClass().start().join();
Or is there another approach to use? ...like this maybe:
new SampleClass().start();
try{Thread.currentThread().join();}catch(InterruptedException e){...}
Thank you very much
new SampleClass().start().join(); This is wrong.
You can achieve similar thing by
SampleClass samClass = new SampleClass();
samClass.start();
samClass.join()
The above code will have same effect as you wanted.
Now your problem is to run the Threads Sequentially. In most of these
cases you don't need threads to execute sequentially (But yes there are some scenarios).
Well If you do have to.
Then you can Do Like this
Thread t1 = ..
Thread t2 = ..
t1.start();
t1.join();
t2.start(); // t2 will start only when t1 dies
t2.join(); //
t3.start(); // t3 will start only when t2 dies..
But the above approach is not good. Because for other thread to start, previous thread
needs to die. In practice We should think of creating threads as an expensive operation
and try to reuse.
The real problem often is like this, You have to execute tasks T1 , T2 , T3 , T4
sequentially but in different Threads T1 && T3 have to run on one threads and T2 and T4
have to run on another.
So here we can use Two threads instead of 4.
Thread1 will run T1 and then Thread2 will run T2 and then Thread1 will run T3 and so on
i.e.
Thread1 -> T1
Thread2 -> T2
Thread1 -> T3
Thread2 -> T4
All task will be executed sequentially but using 2 threads only.
You can solve the problem like below
Thread1 ->run {
while(canIrun) {
executeTask(taskQueue1.next());
notifyThread2();
waitForThread2Signal();
}
}
Thread2 -.run {
while(canIrun) {
waitForThread1Signal();
executeTask(taskQueue2.next());
notifyThread1();
}
}
The wait and notify method can be implemented using CyclicBarrier very easily.
What would be the point? You can get the same effect, without the overhead, by just calling run().
You can use ExecutorService#submit(Runnable runnable).get()
Is it possible to call immediately join()?
No it is not as start() returns void . You cannot chain those methods that way. And you need to invoke join() on a Thread object.
Method start belongs to Thread class. It would be like doing this:
Thread thread = new Thread(someRunnableTask);
//This fails to compile, because start returns NOTHING (void). This variable will not be filled with pointer to our thread object.
Thread ourOriginalThreadPointer = thread.start();
//Hence this variable references to nothing, no method can be called.
ourOriginalThreadPointer.join()
The instanciated thread doesn't need to be anonymous. You can do that:
public static void main(String[] args) {
for(int i=0; i<5; i++){
SampleClass sc = new SampleClass();
sc.start();
try {
sc.join();
} catch (InterruptedException e) {
}
}
}
i heard, sleep() will lock the current sync method/block
But here, when i call sleep() on thread 1, thread 2 is able to access the same block? Can anyone Explain?
Main.java
public class Main {
public static void main(String args[])
{
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
System.out.println("going to start t1");
t1.start();
System.out.println("going to start t2");
t2.start();
}
}
=====================================================================
Thread1.java
public class Thread1 extends Thread{
public void run() {
Syncc s1 = new Syncc();
s1.me("T1:");
}
}
=====================================================================
Thread2.java
public class Thread2 extends Thread{
public void run() {
Syncc s2 = new Syncc();
s2.me("T2:");
}
}
=====================================================================
Syncc.java
public class Syncc{
public void me(String s){
synchronized(this){
for(int i=0; i<=5; i++)
{
System.out.println(s+" "+" "+i);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
==========================================
Output:
going to start t1
going to start t2
T2: 0
T1: 0
T2: 1
T1: 1
T1: 2
T2: 2
T1: 3
T2: 3
T1: 4
T2: 4
T2: 5
T1: 5
BUT according to sleep() method, it should not unlock the current synchronization block right? if so the out put should be..
going to start t1
going to start t2
T1: 0
T1: 1
T1: 2
T1: 3
T1: 4
T1: 5
T2: 0
T2: 1
T2: 2
T2: 3
T2: 4
T2: 5
i mean after thread 1 execution only thread 2 should start right?
Whats the issue?
This is because you have two different instances of Syncc in play here. Each thread has its own copy of Syncc.
Try doing the same with a single instance. You could also synchronize on the static context and try.
To simulate, modify Thread1 and Thread2 to accept an instance of Syncc.
public class Thread1 extends Thread {
private Syncc syncc;
public Thread1(Syncc syncc) {
this.syncc = syncc;
}
public void run() {
this.syncc.me("T1:");
}
}
You can then start them as so:
public static void main(String args[]) {
Syncc syncc = new Syncc();
Thread1 t1 = new Thread1(syncc);
Thread2 t2 = new Thread2(syncc);
System.out.println("going to start t1");
t1.start();
System.out.println("going to start t2");
t2.start();
}
Rules of Sleep, Yield and Join
Sleeping is used to delay execution for a period of time, and no locks are
released when a thread goes to sleep.
A sleeping thread is guaranteed to sleep for at least the time specified in
the argument to the sleep() method (unless it's interrupted), but there is
no guarantee as to when the newly awakened thread will actually return to
running.
The sleep() method is a static method that sleeps the currently executing
thread's state. One thread cannot tell another thread to sleep.
The setPriority() method is used on Thread objects to give threads
a priority of between 1 (low) and 10 (high), although priorities are not
guaranteed, and not all JVMs recognize 10 distinct priority levels—some
levels may be treated as effectively equal.
If not explicitly set, a thread's priority will have the same priority as the
priority of the thread that created it.
The yield() method may cause a running thread to back out if there are
runnable threads of the same priority. There is no guarantee that this will
happen, and there is no guarantee that when the thread backs out there
will be a different thread selected to run. A thread might yield and then
immediately reenter the running state.
The closest thing to a guarantee is that at any given time, when a thread
is running it will usually not have a lower priority than any thread in the
runnable state. If a low-priority thread is running when a high-priority thread
enters runnable, the JVM will usually preempt the running low-priority
thread and put the high-priority thread in.
When one thread calls the join() method of another thread, the currently
running thread will wait until the thread it joins with has completed. Think
of the join() method as saying, "Hey thread, I want to join on to the end
of you. Let me know when you're done, so I can enter the runnable state."
http://www.amazon.com/SCJP-Certified-Programmer-Java-310-065/dp/0071591060
You have created two Synch objects each object corresponding to one thread . Each object has its own copy of me. Hence when your start each thread, withing the run method the thread is calling its own copy of the function me. Since the two thread act only on their copy this works like a single thread scenario. If you do want to test a multithread scenario then make the method me static(class level method) and apply a class level lock.
Thread1.java
public class Thread1 extends Thread{
public void run() {
Syncc.me("T1:");
}
}
Thread2.java
public class Thread2 extends Thread{
public void run() {
Syncc.me("T2:");
}
}
Syncc.java
public class Syncc{
public static void me(String s){
synchronized(Syncc.class){
for(int i=0; i<=5; i++)
{
System.out.println(s+" "+" "+i);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
The Java thread join() method confuses me a bit. I have following example
class MyThread extends Thread {
private String name;
private int sleepTime;
private Thread waitsFor;
MyThread(String name, int stime, Thread wa) { … }
public void run() {
System.out.print("["+name+" ");
try { Thread.sleep(sleepTime); }
catch(InterruptedException ie) { }
System.out.print(name+"? ");
if (!(waitsFor == null))
try { waitsFor.join(); }
catch(InterruptedException ie) { }
System.out.print(name+"] ");
And
public class JoinTest2 {
public static void main (String [] args) {
Thread t1 = new MyThread("1",1000,null);
Thread t2 = new MyThread("2",4000,t1);
Thread t3 = new MyThread("3",600,t2);
Thread t4 = new MyThread("4",500,t3);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
In which order are the threads terminated?
What actually confuses you about Thread.join()? You haven't mentioned anything specific.
Given that Thread.join() (as the documentation states), Waits for this thread to die, then t4 will wait for t3 to complete, which will wait for t2 to complete, which will wait for t1 to complete.
Therefore t1 will complete first, followed by t2, t3, and t4.
It would terminate in order t1, t2, t3, t4... join causes the currently executing thread to wait until the thread it is called on terminates.
There is a main thread which starts the four customs threads you created t1,t2,t3 and t4. Now when join() method is invoked on a thread and no argument(time) is supplied(which makes it 0 by default meaning maximum wait time is forever) then the calling thread will wait for the thread on which join was invoked to terminate.
When t1.start() is called it's corresponding run() method is invoked by the JVM. Since waitsFor argument is null for t1 it will simply terminate by printing it's name. Since you are adding sleep t2,t3,t4 would be started by the time t1 completes it's sleep. Now t2 will wait for t1 to terminate as we are calling join on t1 from t2. Similarly t3 will wait for t2 and t4 will wait for t3. So youe execution will go t1->t2->t3->t4.
However if t1 terminates before t2 calls join on it, join will simply return because at that point(when t2 calls join on t1) isAlive() will be false.
Surely the order of thread termination would be from t1, t2, and so on here. May be you will get a clear understanding of join() method in java thread from here also http://findnerd.com/list/view/Java-Thread-Join-Example/4465/