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.
Related
So I was trying to do some testing based off some things I know about the Java Memory Model (JMM) because I wanted to see how they applied to a initialization+assignment in a try-catch block with an exception thrown, and I obtained the results I wanted (not related, but I wanted to know if in a try-catch if the allocation could happen before the initialization, and in turn before some exception was thrown, could some other Thread see the uninitialized Object before the Exception was thrown - the answer seems to be no), however I encountered something odd related to my Thread running.
Basically, my Thread never seems to exit. I ran my code to completion in a debugger, and I can see the two Threads running. My main Thread being Thread, and the Thread I created Thread-1. After I complete the main method, my main Thread goes away and is replaced with DestroyJavaVM, as expected. However, Thread-1 seems to be waiting on something.
The part that really confuses me, other than the code being too simple to screw up, is that if I put a
System.out.print("");
inside of the while block, then the slow down caused by I/O seems to cause the Thread to "catch-up" on whatever it was doing, and see the interrupt. Another thing I noticed, is that if I put a breakpoint on the "finished" #println() statement, that the Thread will break on that line, and allow me to continue which causes the print statement in the standard-out, and the program exits. That doesn't make a lot of sense to me. What is happening behind the scenes that causes the created Thread not see the interrupt?
Here is the code I have for my testing, with the unimportant bits removed that were related to me testing the JMM:
public class Foo{
static Foo p;
public static void main(String [] args){
Thread t = new Thread(new Runnable(){
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
}
System.out.println("finished");
}
});
t.start();
for(int i = 0; i < 100000; i++){
try{
p = new Foo();
}catch(Exception pse){
}
}
t.interrupt();
System.out.println("main-method-completed");
}
}
You have probably reproduced the bug JDK-6772683 : Thread.isInterrupted() fails to return true on multiprocessor PC.
As long as the thread runs its while-loop it won't get any messages from other threads in the system. If you do, for instance, Thread.sleep(1); the thread is paused, and a context switch to something else occurs. When the thread is restored, it will get the interrupt notification from some the main loop thread.
If you want to stop the loop in the thread you could either use a volatile variable (these are written and read explcitly from shared memory and are quite expensive), or use, for instance, an java.util.conncurrent.atomic.AtomicBoolean, which at least in theory could use some less expensive method for communicate the its state between threads.
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.
If I have the following dummy code:
public static void main(String[] args) {
TestRunnable test1 = new TestRunnable();
TestRunnable test2 = new TestRunnable();
Thread thread1 = new Thread(test1);
Thread thread2 = new Thread(test2);
thread1.start();
thread2.start();
}
public static class TestRunnable implements Runnable {
#Override
public void run() {
while(true) {
//bla bla
}
}
}
In my current program I have a similar structure i.e. two threads executing the same Run() method. But for some reason only thread 1 is given CPU time i.e. thread 2 never gets a chance to run. Is this because while thread 1 is in its while loop , thread 2 waits?
I'm not exactly sure, if a thread is in a while loop is it "blocking" other threads? I would think so, but not 100% sure so it would be nice to know if anyone could inform me of what actually is happening here.
EDIT
Okay, just tried to make a really simple example again and now both threads are getting CPU time. However this is not the case in my original program. Must be some bug somewhere. Looking into that now. Thanks to everyone for clearing it up, at least I got that knowledge.
There is no guarantee by the JVM that it will halt a busy thread to give other threads some CPU.
It's good practice to call Thread.yield();, or if that doesn't work call Thread.sleep(100);, inside your busy loop to let other threads have some CPU.
At some point a modern operating system will preempt the current context and switch to another thread - however, it will also (being a rather dumb thing overall) turn the CPU into a toaster: this small "busy loop" could be computing a checksum, and it would be a shame to make that run slow!
For this reason, it is often advisable to sleep/yield manually - even sleep(0)1 - which will yield execution of the thread before the OS decides to take control. In practice, for the given empty-loop code, this would result in a change from 99% CPU usage to 0% CPU usage when yielding manually. (Actual figures will vary based on the "work" that is done each loop, etc.)
1The minimum time of yielding a thread/context varies based on OS and configuration which is why it isn't always desirable to yield - but then again Java and "real-time" generally don't go in the same sentence.
The OS is responsible for scheduling the thread. That was changed in couple of years ago. It different between different OS (Windows/Linux etc..) and it depends heavily on the number of CPUs and the code running. If the code does not include some waiting functionality like Thread.yield() or synchhonized block with a wait() method on the monitor, it's likely that the CPU will keep the thread running for a long time.
Having a machine with multiple CPUs will improve your parallelism of your application but it's a bad programming to write a code inside a run() method of a thread that doesn't let other thread to run in a multi-threaded environment.
The actual thread scheduling should be handled by the OS and not Java. This means that each Thread should be given equal running time (although not in a predictable order). In your example, each thread will spin and do nothing while it is active. You can actually see this happening if inside the while loop you do System.out.println(this.toString()). You should see each thread printing itself out while it can.
Why do you think one thread is dominating?
So I am trying to work with threads for a game I am making. I am very new to the subject so I may not understand correctly. My question is how does the currentThread() method work in the Thread class of the java API. The API says "Returns a reference to the currently executing thread object.", but as far as I understand multiple threads run at the same time. How is it possible to return only one executing thread?
The code that calls currentThread will be executing in one of the threads, not in all of them, so it can get that thread specifically.
Suppose you have list of instructions printed on a piece of paper. A person reads the instructions and performs them. The instructions are a program. The person is a thread. You could make many copies of the paper and pass them out to many people. If the instructions say something like, "slap yourself," yourself refers to whomever is reading that instruction from that paper. Likewise, Thread.currentThread() refers to the thread that is executing that call to currentThread().
When an instruction in your code is executed, it is executed within a specific thread. This is the thread returned by that method.
Obviously, if a specific method is executed by multiple threads, each execution might return a different value for Thread.currentThread().
You could try this short example to get a better idea of what is going on and in particular the fact that the 2 threads execute in parallel. You should see that t1 will run a few loop then t2 will do the same and back to t1 etc (you might need to increase the number of loops from 5 to a higher number depending on your machine):
public class TestThread {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread());
}
}
};
Thread t1 = new Thread(r, "t1");
Thread t2 = new Thread(r, "t2");
t1.start();
t2.start();
}
}
"The currently executing thread" means that the system scheduler gave some time to this thread to execute its code.
When writing a single threaded application, you can reason on your program like a series of instruction, each executed after the previous one is finished (this is a rough approximation, but conceptually compilator and processor try to simulate that and work as if this was really what was happening).
When you use multiple thread, each thread has its own series of instruction. A new thread when created is passed a entry point (a method), and will continue executing from them. Each thread is independent from the other thread in their execution (it will simply execute one instruction after the other), though they share memory and thus side-effect from one thread can affect another.
So for some code to be executed, it must be done in the context of one thread (there is one created by the operating system when your application start, that start its execution at the Main method). When the function currentThread is called, it is in one of those context.
The java runtime when creating a thread will store a reference to that Thread object in the thread context, and the currentThread will just lookup there and return the current thread.
At any given point in time, only one thread will be executing(live), so Thread.currentThread() returns the details of the currently executing Thread. e.g., Thread_name, priority, method_name.
Multiple threads are not running at the same time and there is thread switching between multiple threads. Processor can execute one task at a time so one thread at a a time executed. So we get the reference of currently running thread.
In javadoc there is said that yield method
Causes the currently executing thread object to temporarily pause and allow other threads to execute.
And Katherine Sierra and Bert Bates SCJP book says that
yield() is supposed to do is
make the currently running thread head back to runnable to allow other threads of
the same priority to get their turn.
So what actually method is doing?
Given a multi-threaded application, yield will cause the currently executing thread to pause execution and be set in a waiting state. The JVM will then begin running another thread that was previously in a waiting state.
I believe the same thread that just yielded could technically be scheduled to start again.
And I have yet to see this in the wild though. So I think it is safe to avoid.
To elaborate:
In a multi-threaded environment threads are scheduled and unscheduled off and on at the JVM's will. So, even if yield is not called in code, your thread can/will automatically yield to other threads when the JVM decides it should. This allows multi-threading to work in an environment with only one processing core.
Calling yield simply tells the JVM to put the current thread in a waiting state even if the JVM wasn't going to.
I shall attempt an illustration:
The following is a very simplified illustration of the execution of 2 threads over time (assume 1 core)-
Thread\Time 1 2 3 4 5 6 7 8 9
Thread 1 ----------- ----- -------
Thread 2 ------- ---------- ------
Whenever you see a '-' that means a thread is executing. A ' ' means that the thread is waiting. As you can see, only 1 thread can actually run at a time. So, while 1 runs, the other waits. What yield is intended to do is give other threads a chance to run ahead of the currently running thread.
yield() is generally used when you are waiting on a thread for something to occur but don't want to block the CPC cycles with something like while(condition){ ...} . The way yield() works differ from platform to platform and depends on the Thread Scheduler and you shouldn't rely on it behaving in a particular way.
It originates from the time of cooperative multitasking.
The basic idea is, the processor executes only one thread until:
this thread ends
this thread does some blocking operation, like object.wait() or Thread.sleep, waiting on some IO operation to complete, waiting for some object monitor, or similar.
this thread invokes Thread.yield().
In each of this cases the thread scheduler then selects another thread to execute. So, to be fair to other threads, you would in longer loops without any blocking operations regularly call yield(). (If no other thread is ready to run, then the same thread would be scheduled again, so no really big performance loss.)
In modern VMs thread switching can occur on any point, not only these listed, threads may even be executed simultaneously, so it is not really necessary, and some VMs may ignore it altogether (similar to System.gc().)
yield() method is there to make sure that all same priority threads in a application would not cause starvation. For e.g. five threads are there in a application and all of them are of same priority. Now suppose one thread got chance to run and this thread is taking so long to complete its task and hence other threads wont get chance to run. So to avoid this kind of situations yield() is there to rescue.
Ultimately, the call to yield() results in calling os methods like this, which in principle would put the task itself back in to the run queue and let the next task run (source):
/**
* sys_sched_yield - yield the current processor to other threads.
*
* This function yields the current CPU to other tasks. If there are no
* other threads running on this CPU then this function will return.
*/
SYSCALL_DEFINE0(sched_yield)
{
/*
* lock this runqueue and disable interrupts.
*/
struct rq *rq = this_rq_lock();
schedstat_inc(rq, yld_count);
current->sched_class->yield_task(rq);
/*
* Since we are going to call schedule() anyway, there's
* no need to preempt or enable interrupts:
*/
__release(rq->lock);
spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
_raw_spin_unlock(&rq->lock);
preempt_enable_no_resched();
schedule();
return 0;
}
Threads may be in states ready (runnable), blocked (e.g., waiting for some io to finish), or running; this is common to all thread implementations, although some particular implementations may have more states.
Yield causes the thread to change from running to runnable, and wait for the scheduler to change it to running again, in the future. This is what is meant in the SCJP book.
To the thread, it seems like it has been paused for a while, like described in the javadoc. So both statements are correct, just differently phrased.
Hope it helps!
package yield;
public class ThreadYieldApp {
Thread th1 = new Thread("Thread 1") {
public void run() {
for(int i = 0; i <= 10; i++) {
System.out.println("Before Yield - " + Thread.currentThread().getName() + " at index - " + i);
//Currently pauses the thread and checks for other threads of same priority, and passes control to it based on Thread Scheduler pick
Thread.yield();
System.out.println("Currently running - " + Thread.currentThread().getName() + " at index - " + i);
}
}
};
Thread th2 = new Thread("Thread 2") {
public void run() {
for(int i = 0; i <= 10; i++) {
System.out.println("Currently running - " + Thread.currentThread().getName() + " at index - " + i);
}
}
};
public static void main(String[] args) {
ThreadYieldApp threadYieldApp = new ThreadYieldApp();
threadYieldApp.th1.start();
threadYieldApp.th2.start();
}
//Happy coding -- Parthasarathy S
}