Multithreading synchronization issues - java

I have code like this:
public class OtherClass {
// OtherClass
public synchronized static void firstMethod() {
System.out.println("FIRST METHOD");
}
public synchronized static void secondMethod() {
System.out.println("SECOND METHOD");
// In actual code I would have try catch for this but here I just didn't
// include it
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class MainClass {
// main method of MainClass
public static void main(String args[]) {
Thread firstThread = new Thread() {
public void run() {
while (true) {
OtherClass.firstMethod();
}
}
};
Thread secondThread = new Thread() {
public void run() {
while (true) {
OtherClass.secondMethod();
}
}
};
secondThread.start();
firstThread.start();
}
}
The reason I start the 2nd thread first is because I want the secondMethod of OtherClass to execute first. I should see "FIRST METHOD" and "SECOND METHOD" in the console output every 5 seconds. The reason being is that since Thread.sleep does not relinquish the lock, for 5 seconds the first thread doesn't have access to the first method because the second thread has got a lock on the class while it's in the second method which tells the thread to sleep for 5 seconds. But I get very unexpected results. All I get in the console output is "SECOND METHOD" every 5 seconds. The firstMethod isn't called.

Ignoring compilation problems in your code.
That's just coincidence. The thread scheduler simply decides to continue executing the second thread which reacquires the lock too fast.
Run it long enough (or with a shorter sleep time for faster results) and you'll see the other method get invoked.

The reason I start the 2nd thread first is because I want the secondMethod of OtherClass to execute first.
That's not how threads work. That's not what threads are for. Threads provide no guarantees of what happens before what else except where you provide explicit synchronization between them; And generally speaking, the more synchronization you use, the less you will benefit from having multiple threads.
In your example, you have explicit synchronization that prevents any concurrent executions of firstMethod() and secondMethod(), but you have nothing that guarantees which one will run first, and which one will run second. Chances are, that main() will terminate before either of them runs. At that point, it's up to the scheduler to pick which one will run when. There is no requirement that it start them in the same order that your code called their start() methods.
Your example may be educational, but it also is an example of when not to use threads. Your synchronization is very heavy handed. Your program basically does two things, firstMethod() and secondMethod(), and the synchronization insures that they can not be overlapped. In production software, if you have two tasks that must not overlap, then it'll simplify your program's logic if they are always performed by the same thread.
All I get in the console output is "SECOND METHOD" every 5 seconds. The firstMethod isn't called.
Your question was edited before I got to see it, so I don't know whether you're talking about the original version, or the fixed version. But in any case:
The synchronization in your program does not guarantee that the two threads take turns. All it does is prevent them both from printing at the same time.
Each of your threads runs a loop that grabs the lock, prints something, releases the lock, and then immediately tries to grab the lock again. When a running thread releases a lock, and then immediately tries to get it again, the chances are it will succeed. It doesn't matter that some other thread was waiting for the lock. The OS doesn't know what your program is trying to accomplish, but it does know that it can make more efficient use of the CPU by letting a thread continue to run instead of blocking it and un-blocking some other thread.
You will need to use some additional synchronization to make the threads take turns, but like I said, in a real program, the more synchronization you use, the less benefit there is to using threads.

Your processor won't execute your Threads at the same time; it'll run your second thread every time bevore your first thread.
The behaviour is clear: Your processor executes your second thread. Then, the processor executes your first thread and sees that it is locked by your second thread. After 5 seconds, your second thread is called again. It makes the output, releases the lock and locks it again. If your first thread is called again, it is locked again.
To fix this, add Thread.yield() at the end of your while. This will make the processor call the first thread before continuing to execute your second thread (the first thread won't be the only one that is called, it just removes your second thread 1 time from it's execution). Then your first thread gets the lock, waits 5 seconds, outputs and calls Thread.yield(); then your second thread gets the lock again and so on.

What you are experiencing is thread starvation. In your case, one thread is being blocked indefinitely waiting to enter a synchronization block because the other thread is constantly allowed access.
To overcome thread starvation you need to employ some sort of fairness locking. Locks that are conceived as fair give priority to the threads waiting the longest to acquire said lock. Such a locking strategy eliminates the possibility of thread starvation and insures all waiting threads will be executed at some time.
Fairness locking in Java can easily be accomplished by using a ReentrantLock with a fairness parameter set to true.

Related

ReentrantLock Condition how does signallAll() work?

I am trying to understand How does signalAll() not break the critical section for example
//Some Class Here is Trying to use an resource which is to to initialized in an seperate thread
ReentrantLock lock=new ReentrantLock();
Condition wait=lock.newCondition();
Resource res=new Resource(lock); //An Important Resource Which Should Be Accessed Only By One Thread At A Time
void doStuff()
{
lock.lock();
try
{
if(!res.initialized.get()) //Check If Resource Was Previously Not Initialized
{
res.init();//Spawns An Seperate Thread For Initialization
wait.await();//If Resource Is Not Initialized Make Whatever Thread Which Reached This Point Wait
}
res.use(); //Here Is What I Don't Understand If Let's Say 5 threads were parked in the previous statement then when signalAll() is called won't all 5 threads wake up simultaneously and resume execution at this point and use this resource at the same time and break this resource? But it dosen't turn out like that why?
}
}
finally{lock.unlock();}
}
private static final class Resource extends Thread
{
private final ReentrantLock lock;
private final Condition init;
private final AtomicBoolean
started=new AtomicBoolean(false),
initialized=new AtomicBoolean(false);
private Resource(ReentrantLock lock)
{
this.lock=lock;
this.init=lock.newCondition();
}
private void init()
{
if(!initialized.get())
{
if(!started.get())
{
start();
started.set(true);
}
while(!initialized.get()){init.awaitUninterruptibly();}//In case of spurrous wakeups check repeatedlly
}
}
private void use(){}//Important Stuff
private int get(){return 5;}
#Override
public void run()
{
lock.lock();
try
{
TimeUnit.SECONDS.sleep(5);
initialized.set(true);
init.signalAll(); //This should in the above example wake up all 5 threads simultaneously and break the critical section but that does not happen how?
}
catch(InterruptedException ex){}
finally{lock.unlock();}
}
}
With just signal() only one thread wakes up and resumes execution at the critical section so nothing breaks but with signalAll() multiple threads resumes execution at the point it was parked[i.e inside the critical section] so how does nothing break? and when/where should we use each i.e best practises
The short answer:
await() does not only suspend the current thread, it also releases the lock. signalAll() wakes up all suspended threads but each thread has to re-acquire the lock before the await() call can return. With it, even after calling notifyAll() the critical section can only be entered by a thread after the thread that acquired the lock before relinquishes the lock.
The long answer:
For better understanding - let's pretend that neither await(), singal() nor signalAll() would exist in Java. How would you wait for the asynchronous initialization of your resource? Your code would probably look something like this:
void doStuff(Resource resource) throws InterruptedException {
lock.lock();
try {
while (!resource.isInitialized()) {
resource.startAsyncInit();
lock.unlock();
Thread.sleep(100);
lock.lock();
}
doSomethingWith(resource);
} finally {
lock.unlock();
}
}
But this would have the following drawback:
Each thread that waits for initialization is suspended and woken up again and again.
Each single thread acquires the lock and releases the lock again and again.
The more frequent you do this and the more threads are waiting the more expensive
does it get. This busy waiting consumes CPU. Without an explicit sleep the code would easily
lead to 100% CPU usage.
await() allows you to replace the busy waiting with a signal-based mechanism.
All waiting threads are suspended and do not consume any CPU while they are waiting.
Only sporadically occuring spurious wake-ups (at least on some systems) may consume some CPU.
When to use singal(), signallAll() in general:
Waking up a thread and suspending a thread is not for free and gets more expensive with
the number of threads. If you have a resource that has to be initialized
before it can be used concurrently by all threads it makes sense to wake up all threads at once by calling signalAll().
But think of a consumer/producer pattern with multiple consumer threads and multiple producer threads where a single producer thread provides only one work item that is processed by one consumer thread. In this case it would make much more sense that a producer thread wakes up only one consumer thread instead of all. Otherwise all awakened threads would first compete for the single work item, one would win and all others would have to be sent back to sleep again. This would have to be repeated every time when a single work item is produced. When a lot of work items are produced in short time
you would finally loose all the advantage of the singalling. The majority of threads would be suspended and woken up again and again, they would compete for one single item again and again and you would finally end up with nearly the same overhead as the example above with busy waiting but without an explicit sleep ;-)
signal() vs signalAll() in your example:
When the first thread gets the hold of the lock it calls the init() method, starts the thread for initialization and then releases the lock when it calls awaitUninterruptibly(). The initialization thread in the meanwhile tries to acquire the lock but it will not get it until awaitUninterruptibly() is called.
Locks are by default unfair. This means that it is not guaranteed that the longest-waiting thread will get the lock first. When awaitUninterruptibly() is actually called and the lock is released other theads may have already tried to acquire the lock in the meanwhile by calling the lock() method. Even when your initialization thread tried to acquire the lock first, it is not guaranteed that it will get the lock before any other thread. Every other thread that will get the lock before your initialization thread will be able to call the await() method. If you then only call singal() in your initialization thread all threads that were able to get to the await() call would never be woken up and sleep forever. To avoid this, it is essential to use singalAll() in your example. Another possibility would be to use a "fair" lock (see the JavaDoc of the ReentrantLock). With a "fair" lock it shouldn't make any difference whether you call singal() or signalAll(). But since "fair" locks have quite an overhead I would suggest to keep the unfair lock and use singalAll().
Whether you run into a situation where some threads sleep forever depends on the right timing. So you propably may run this code on one host hundreds of times without any problem but run into this situation frequently on other hosts. Even worse, in environments with spurious wake-ups you would run into this only from time to time ;-)

End Java threads after a while statement has been run

I am having an issue ending threads once my program my has finished. I run a threaded clock object and it works perfectly but I need to end all threads when the time ´==´ one hour that bit seems to work I just need to know how to end them. Here is an example of the code I have and this is the only thing that runs in the run method apart from one int defined above this code.
#Override
public void run()
{
int mins = 5;
while(clock.getHour() != 1)
{
EnterCarPark();
if(clock.getMin() >= mins)
{
System.out.println("Time: " + clock.getTime() + " " + entryPoint.getRoadName() + ": " + spaces.availablePermits() + " Spaces");
mins += 5;
}
}
}
But when you keep watching the threads that are running in the debug mode of netbeans they keep running after an hour has passed not sure how to fix this. I have tried the interrupt call but it seems to do nothing.
There are two ways to stop a thread in a nice way, and one in an evil way.
For all you need access to the object of the thread (or in the first case a Runnable class that is executed on that thread).
So your first task is to make sure you can access a list of all threads you want to stop. Also notice that you need to make sure you are using threadsafe communication when dealing with objects used by several threads!
Now you have the following options
Interrupt mechanisme
Call Thread.interrupt() on each thread. This will throw an InterruptedException on the thread if you are in a blocking function. Otherwise it will only set the isInterrupted() flag, so you have to check this as well. This is a very clean and versatile way that will try to interrupt blocking functions by this thread. However many people don't understand how to nicely react to the InterruptedException, so it could be more prone to bugs.
isRunning flag
Have a boolean 'isRunning' in your thread. The while loop calls a function 'stopRunning()' that sets this boolean to false. In your thread you periodically read this boolean and stop execution when it is set to false.
This boolean needs to be threadsafe, this could be done by making it volatile (or using synchronized locking).
This also works well when you have a Runnable, which is currently the advised way of running tasks on Threads (because you can easily move Runnables to Threadpools etc.
Stop thread (EVIL)
A third and EVIL and deprecated way is to call Thread.stop(). This is very unsafe and will likely lead to unexpected behavior, don't do this!
Make sure that the loop inside every thread finishes - if it does in all the threads, it does not make sense that there are prints in the output. Just note that what you are checking in each loop condition check if the current hour is not 1 PM, not if an hour has not passed.
Also, your threads garbage collected, which means that the Garbage Collector is responsible for their destruction after termination - but in that case they should not output anything.
A volatile variable shared by all the Threads should help to achieve the goal. The importance of a volatile variable is that each of the Threads will not cache or have local copy but will need to directly read from the main memory. Once it is updated, the threads will get the fresh data.
public class A{
public static volatile boolean letThreadsRun = true;
}
// inside your Thread class
#Override
public void run()
{ // there will come a point when A.letThreadsRun will be set to false when desired
while(A.letThreadsRun)
{
}
}
If two threads are both reading and writing to a shared variable, then
using the volatile keyword for that is not enough. You need to use
synchronization in that case to guarantee that the reading and writing
of the variable is atomic.
Here are links that may help you to grasp the concept:
http://tutorials.jenkov.com/java-concurrency/volatile.html
http://java.dzone.com/articles/java-volatile-keyword-0
If these threads are still running after your main program has finished, then it may be appropriate to set them as daemon threads. The JVM will exit once all non-daemon threads have finished, killing all remaining daemon threads.
If you start the threads like:
Thread myThread = new MyThread();
myThread.start();
Then daemon-izing them is as simple as:
Thread myThread = new MyThread();
myThread.setDaemon(true);
myThread.start();
It's a bad practice to externally terminate threads or to rely on external mechanisms like kill for proper program termination. Threads should always be designed to self-terminate and not leave resources (and shared objects) in a potentially indeterminate state. Every time I have encountered a thread that didn't stop when it was supposed to, it was always a programming error. Go check your code and then step through the run loop in a debugger.
Regarding your thread, it should self-terminate when the hour reaches 1, but if it is below or above 1, it will not terminate. I would make sure that clock's hour count reaches one if minutes go past 59 and also check that it doesn't somehow skip 1 and increment off in to the sunset, having skipped the only tested value. Also check that clock.getHour() is actually returning the hour count instead of a dummy value or something grossly incorrect.
Have you considered using an ExecutorService ? It behaves more predictably and avoids the overhead of thread creation. My suggestion is that you wrap your while loop within one and set a time limit of 1 hr.
Using Thread.interrupt() will not stop the thread from running, it merely sends a signal to you thread. It's our job to listen for this signal and act accordingly.
Thread t = new Thread(new Runnable(){
public void run(){
// look for the signal
if(!Thread.interrupted()){
// keep doing whatever you're doing
}
}
});
// After 1 hour
t.interrupt();
But instead of doing all this work, consider using an ExecutorService. You can use Executors class with static methods to return different thread pools.
Executors.newFixedThreadPool(10)
creates a fixed thread pool of size 10 and any more jobs will go to queue for processing later
Executors.newCachedThreadPool()
starts with 0 threads and creates new threads and adds them to pool on required basis if all the existing threads are busy with some task. This one has a termination strategy that if a thread is idle for 60 seconds, it will remove that thread from the pool
Executors.newSingleThreadExecutor()
creates a single thread which will feed from a queue, all the tasks that're submitted will be processed one after the other.
You can submit your same Runnable tasks to your thread pool. Executors also has methods to get pools to which you can submit scheduled tasks, things you want to happen in future
ExecutorService service = Executors.newFixedThreadPool(10);
service.execute(myRunnableTask);
Coming to your question, when you use thread pools, you have an option to shut down them after some time elapsed like this
service.shutdown();
service.awaitTermination(60, TimeUnit.MINUTES);
Few things to pay attention
shutdown() Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.
awaitTermination() is waiting for the state of the executor to go to TERMINATED. But first the state must go to SHUTDOWN if shutdown() is called or STOP if shutdownNow() is called.

Thread variable after call start and run

I realized that this code:
public class TestThread3 extends Thread {
private int i;
public void run() {
i++;
}
public static void main(String[] args) {
TestThread3 a = new TestThread3();
a.run();
System.out.println(a.i);
a.start();
System.out.println(a.i);
}
}
results in 1 1 printed ... and i don't get it. I haven´t found information about how to explain this. Thanks.
results in 1 1 printed
So the first a.run(); is called by the main-thread directly by calling the a.run() method. This increments a.i to be 1. The call to a.start(); then is called which actually forks a new thread. However, this takes time to do so the i++; operation most likely has not started before the System.out.println(...) call is made so a.i is still only 1. Even if the i++ has completed in the a thread before the println is run, there is nothing that causes the a.i field to be synchronized between the a thread and the main-thread.
If you want to wait for the spawned thread to finish then you need to do a a.join(); call before the call to println. The join() method ensures that memory updates done in the a thread are visible to the thread calling join. Then the i++ update will be seen by the main-thread. You could also use an AtomicInteger instead of a int which wraps a volatile int and provides memory synchronization. However, without the join() there is still a race condition between the a thread doing the increment and the println.
// this provides memory synchronization with the internal volatile int
private AtomicInteger i;
...
public void run() {
i.incrementAndGet();
}
...
a.start();
// still a race condition here so probably need the join to wait for a to finish
a.join();
System.out.println(a.i.get());
This behavior can change at any point of time because when a.start() is called, the thread is scheduled for process, not necessary the OS will let it start executing on CPU.
Once a.start() returns, you actually have two threads (one is for main and another is a new thread), and the main would still be running.
The expected result could only come if following happens,
Time
T1 main method calls a.start()
T2 jvm / os schedules thread for execution
T3 a.start() returns and main thread gets context-switched and suspended for other threads.
T4 Spawned thread gets execution context, and its run method is called, which increments value
T5 context switch happens and main thread gets the control back
T6 main thread would print 2
Jatan
You have two main issues here to clear up. I also recommend you examine Gray's answer for more technical information.
**Note: This just skims the surface, but most of the other answers take for granted the background knowledge on these Computer Science topics that I believe you have not yet mastered.
First, threads are not guaranteed order of execution. In general, you should only use threads if they can work asynchronously (independently timed). For this example, you have a timing-specific expected outcome, so threading should probably just be avoided.
This, however, isn't your only issue.
As is, your code also has what is called a Race Condition. A Race Condition occurs when two different threads (or processes) have access to read/manipulate the same data -- In your case, reading i and incrementing via i++.
For example,
Imagine that you and a friend both have a dollar. The Ice Cream Man drives along and stops in front of you. The Ice Cream Man only has one ice cream cone left. There are a couple of ways this could play out:
You are faster than your friend and buy the cone first.
You are slower than your friend and he buys the cone first.
You decide to split the ice cream cone and both pay $0.50.
You two fight and someone else gets to buy the last ice cream cone while you two are distracted.
To mirror this back to the computer,
The main thread where you are printing continues to run even after you started the second thread. (Threads are linked to the same process, so when main returns, the other threads "die". It is possible the thread, even though it a.start()'ed, doesn't finish or may not even get a chance to run at all!)
The other thread gets to run and completes before returning to the main thread.
You take turns executing and everyone gets to do a few lines of code. The out come is really asynchronous here. And this can very likely happen.
The java application process loses the CPU and someone else gets to run (potentially accessing similar shared information.)
TL;DR -
If you want to ensure execution order, then just DO NOT use threads.
There are some cases where syncing up at certain points along the way would be nice. For these cases, you can join the threads (wait for one to finish before continuing), or lock the Race Condition with a Mutex or Semaphore (more advanced synchronization techniques).
I recommend doing some reading on these topics before attempting to jump into battle with the monstrous operating system.

Java: Two threads, interrupting eachother

I want to write a code with two different threads. The first one does somethin, the second one waits a specific time. The thread that ends first should interrupt the other one.
My problem is now, that the thread, I initialized first, cannot access/interrupt the second one, it always gives out the "symbol not found"-error. If I swap the positions of the threads in the code, it is the same, only the other way around.
Is there a possibility, to make both threads "global" and accessable by the other one? Please give coding examples, where to put the public void main, the void run(), etc., if possible, so I just need to add the code itself.
Thanks
Code examples:
public class FTPUpload extends Thread {
public static void main (String args[]) {
_//some code_
final Thread thread1 = new Thread(){;
public void run() {
_//code of thread1_
}
final Thread thread2 = new Thread(){;
public void run() {
_//code of thread2_
}
thread1.start();
thread2.start();
}
}
For your question is (currently?) a bit vague, my answer may not be that helpful. But...
Try declaring the Thread objects first and use them later. So each might be know to the other.
You can create a bool static Variable which both can access and once one of them is finished sets it to true, and you have to check this variable during the job in each thread, either on different places or if you have a loop in the loop for example.
Alternatively you can write a dummy file somewhere by the thread finished 1st and keep checking if file exists in both threads. The main idea is having a shared resource both can access.
Read this Question it very informative: Are static variables shared between threads?
My Idea May not work up to some answers but the one with the file should actually work.
A typical solution for communicating between 2 threads is to use condition variables. Thread1 could block on the condition variable, then when Thread2 has done what it needs to do and wants to tell Thread1 to go, it signals Thread1 via the condition variable, thus releasing its block. Both threads must be initialized with the same condition variable. Here is an example.
If you want both threads to wait until the other is initialized, this can be performed using a barrier sync (called a CyclicBarrier in Java). If Thread1 hits the barrier sync first it will block, until the other thread hits the barrier sync. Once both have hit the barrier sync, then they will continue processing. Here is an example.
Both condition variables and barrier syncs are thread safe, so you dont have to worry about if you need to synchronize them or not.
The general principal is to create a lock and condition outside both threads. The first thread acquires the lock and signals the condition when done. The second thread acquires the lock and awaits the condition (with timeout if needed). I am very concerned that you are relying on Thread.interrupt() which is a bad plan.
final Lock lock = new ReentrantLock();
final Condition done = lock.newCondition();
...
// in thread 1 when finished
lock.lock();
try {
done.signalAll();
} finally {
lock.unlock();
}
...
// in thread 2 for waiting
lock.lock();
try {
done.await(30,TimeUnit.SECONDS); // wait for the done or give up waiting after 30s
} finally {
lock.unlock();
}
Using the lock will ensure that both threads see a consistent view of shared objects, whereas Thread.interrupt() does not guarantee you have passed a boundary
A refinement is to use a CountDownLatch
final CountDownLatch latch = new CountDownLatch(1);
...
// in thread 1
latch.countDown();
...
// in thread 2
latch.await(30,TimeUnit.SECONDS)
This abstracts away the lock.
Others have suggested effectively a spin lock scanning for a file on the file system. Such an approach could lead to thread starvation or if not slower performance than a lock or latch based solution... Though for inter-process as opposed to inter-thread within the one jvm, file based is ok
I recommend the book "Java Concurrency In Practice" if you think you know threading go to a bookshop, open the book and try to predict what the program on page 33 will do... After reading that page you will end up buying the book

Question on Java Thread, output consistent

In the below code the answer is always Started 0 1 2 3 Complete. Im just wondering how it is possible.
If someone could help with the consistency of the output, it would be nice
public class TestOne extends Thread {
/**
* #param args
*/
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
Thread t = new Thread(new TestOne());
t.start();
System.out.println("started");
t.join();
System.out.println("Complete");
}
public void run(){
for(int i=0;i<4;i++){
System.out.println(i);
}
}
Most likely you're getting the same results because, most of the time, the main thread starts a new thread then, before that new thread has a chance to print anything, the main thread prints its started message. The join in the main thread then forces it to wait until the other thread has finished, then it prints Complete.
You have a race condition here. The instant you start the second thread, it's indeterministic as to which order the lines will be output (other than the complete line which is made deterministic by virtue of the wait call, as previously mentioned).
But a race condition doesn't guarantee that you'll get different results on multiple runs, only that it is possible. You still shouldn't rely on that behaviour, of course.
For example, the following code:
public class TestOne extends Thread {
public static void main (String[] args) throws Exception {
Thread t = new Thread (new TestOne());
t.start();
Thread.sleep (1000); // <- Added this.
System.out.println ("Started");
t.join();
System.out.println ("Complete");
}
public void run() {
for (int i = 0; i < 4; i++) {
System.out.println (i);
}
}
}
will output:
0
1
2
3
Started
Complete
Although, even then, the order is not guaranteed as it may take more than a second for the thread to "warm up" - sleep is rarely a good solution to race conditions. I've just used it here for illustrative purposes.
When you say Thread t = new Thread(); nothing special happens because you are not creating a "Thread" per se. It is just an object that has the "characteristics" to become a thread of execution. For the object to be a "Thread" you have to call t.start(); and this is where the magic lies.
When you say t.start() the JVM creates a new stack for the newly created thread to run. It associates that stack to the thread object in question. And then makes it available for scheduling. Basically this means that it queues the thread in the JVM scheduler and in the next time slice it is also available for execution. The JVM actually does a lot more than this, my answer is just oversimplified for your example.
Invariably, meanwhile all these thread + stack creation, your main thread has the opportunity to move to its next instruction which in your case is System.out.println("started");.
Theoretically, what you say is true, "Started" could come anywhere in between 0, 1, 2, 3. However in reality, since your t.start() is an "expensive" method, it takes some time to complete, during which the main thread generally gets the chance to execute its next instruction.
If you want to know the details of t.start(); look into the Java source code.
Clearly, you are seeing a consistent result (and this particular result) because on your machine the call to the child thread's run method is consistently happening after the println in the main thread.
Why is it consistent?
Well, simply because your platform's native thread library is behaving in a consistent fashion!
Typical modern Java virtual machine implementations use the host operating system's native thread support to implement Java threads, and to perform Java thread scheduling. On your machine, the native thread implementation appears to be consistently allowing the current thread to return from the Thread.start() call immediately and keep executing.
However, it is not guaranteed that this will always happen. For instance, if the machine was heavily loaded and the main thread had just about exhausted its current timeslice, it could get descheduled during or immediately after the start call, allowing the new thread to run first.
Furthermore, on another platform the normal scheduler behaviour could be different. The scheduler could consistently cause the current thread to deschedule and let the new one go first. Or it could happen "randomly".
The JVM and Java library specs deliberately do not specify which thread "goes first" precisely to allow for differences in the thread implementation ... and variation due to differences in hardware, system load and so on.
Bottom line - the apparent consistency you are seeing is an "artifact", and you shouldn't rely on it, especially if you want your application to work on a wide range of JVMs.
Simply put, the scheduling of the started thread with respect to the main thread is JVM implementation dependent. But that being said, most implementations, if not all, will leave the starting thread running to the completion of its timeslice, until it blocks on something, or until it is preempted by a higher priority thread (if preemptive scheduling is being used, also JVM implementation dependent).
The Java spec just does not say very much which is very specific about threading, deliberately to grant JVM writers the most scope for their implementation.
t.join() means "block until thread t has finished", which explains the "Completed" being last.
EDIT: In answer to question re "Started"...
The call to Thread.start() means "please schedule this thread to run", and it will start when java feels like starting it. The chance of that happening between t.start() the println() is platform dependant, but small on systems I've used (thx to # Stephen C for platform info).
This code however outputs 0, Started, 1, 2, 3, Completed:
Thread t = new Thread(new TestOne());
t.start();
try
{
Thread.sleep(100); // Added sleep between t.start() and println()
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Started");
t.join();
System.out.println("Complete");
When you start a thread it takes time (nothing comes for free or occurs instantly)
The thread which is already running will almost always be quicker to print out than a thread which has just started.
If you really want to the order to be different every time you can use run() instead of start() This works because you only have one thread.

Categories

Resources