I'm new to threading in Java. I've been reading some online tutorials, but haven't found much material that addresses how the processing time is split between threads.
I created a Runnable class:
public class HelloThread implements Runnable {
public void run() {
int i = 0;
while(true)
{
System.out.println("New Thread" + i);
i++;
}
}
}
and I start the new thread in:
public static void main (String[] args) {
// Start a new thread
Thread helloThread = new Thread(new HelloThread());
helloThread.start();
int i = 0;
while(true)
{
System.out.println("hello from main thread" + i);
i++;
}
}
The output alternates between the message in the helloThread and in the main thread. How is the processing time split between these two threads? I played around with the setPriority() method, but even when I set the helloThread to a priority of 10, the main thread still gets some processing time.
Thanks!
You cannot predict when a thread will run (as you assume). Even if your thread priority is 10, it is no guarantee that you threads will run at all. Threading depends on the concrete JVM (there are different JVM implementation) as well as on the underlying operating system and even on your hardware (like how many cores you have).
In your example, you have two threads (the main thread and your HelloThread). Both are running. So it is a completely OK that both threads run and print messages. It is the purpose of threads to be scheduled alternating and run in parallel.
It is because they have the same priority. You can add statement like
System.out.println( Thread.currentThread().getPriority() );
Both threads should have priority of 5 based on your example
As Thomas Uhrig explained, even with higher priority, the other thread will still get scheduled and executed. It is nondeterministic.
Related
Well,
I'm trying to understand this case. When i create two thread sharing the same instance of Runnable. Why is this order?
Hello from Thread t 0
Hello from Thread u 1
Hello from Thread t 2
Hello from Thread t 4
Hello from Thread u 3 <----| this is not in order
Hello from Thread u 6
Hello from Thread t 5 <----| this one too
Hello from Thread t 8
Hello from Thread t 9
Hello from Thread t 10
i'll show you the code of two thread:
public class MyThreads {
public static void main(String[] args) {
HelloRunnerShared r = new HelloRunnerShared();
Thread t = new Thread(r,"Thread t");
Thread u = new Thread(r,"Thread u");
t.start();
u.start();
}
}
And concluding, the final question is if i'm running this thread i understand they're not running in order but. Why a thread is keeping or printing a number in disorder?
This is the code for the runnable:
class HelloRunnerShared implements Runnable{
int i=0;
public void run(){
String name = Thread.currentThread().getName();
while (i< 300) {
System.out.println("Hello from " + name + " " + i++);
}
}
}
i thought they would be processed intercalated. It's just an assumption!!
Thanks!
Why do you think threads should be executing in a particular order? It's a nondeterministic phenomenon -- whichever is scheduled first, runs first.
Use the ExecutorService.invokeAll if you want things to run in the order in a fixed order, regardless of their schedule.
There are several things going on:
The OS scheduler can switch between threads any time it wants. There's no fairness requirement, the scheduler may favor one thread over another (for instance, it could be trying to minimize the amount of context-switching).
The only locking going on is on the PrintStream used by the println method, which keeps the threads from writing to the console simultaneously. Which thread acquires the lock on the PrintStream when depends on the OS scheduler. The locks used are the intrinsic ones used with the synchronized keyword, they are not fair. The scheduler can give the lock to the same thread that took it last time.
++ is not an atomic operation. The two threads can get in each other's way updating i. You could use AtomicInteger instead of an int.
Access to i is not protected by a lock or any other means of enforcing a happens-before boundary, so updates to it may or may not be visible to other threads. Just because one thread updates i doesn't automatically mean the other thread will see the updated value right away, or at all (how forgiving the JVM is about this depends on the implementation). In the absence of happens-before boundaries the JVM can make optimizations like reordering bytecodes or performing aggressive caching.
I have set thread's priority in below order
A then B then C .But when I am running below program sometimes B runs before A.
I don't understand this execution as I set B's priority less then A's priority.
public class AThread implements Runnable{
public void run(){
System.out.println("In thread A");
}}
public class BThread implements Runnable {
public void run(){
System.out.println("In thread B");
}
}
public class CThread implements Runnable {
public void run(){
System.out.println("In thread C");
}
}
public class ThreadPriorityDemo {
public static void main(String args[]){
AThread A = new AThread();
Thread tA = new Thread(A);
BThread B = new BThread();
Thread tB = new Thread(B);
CThread C = new CThread();
Thread tC = new Thread(C);
tA.setPriority(Thread.MAX_PRIORITY);
tC.setPriority(Thread.MIN_PRIORITY);
tB.setPriority(tA.getPriority() -1);
System.out.println("A started");
tA.start();
System.out.println("B started");
tB.start();
System.out.println("C started");
tC.start();
}
}
Thread priorities are probably not what you think they are.
A thread's priority is a recommendation to the operating system to prefer one thread over another in any scheduling or CPU allocation decision point where these two threads are involved. But how this is implemented depends on the operating system and the JVM implementation.
JavaMex has a nice discussion of thread priorities. The gist is that:
Priorities may have no effect at all.
Priorities are only one part of a calculation that dictates scheduling.
Distinct Java priority values may be translated into the same value in practice (so for example, priority 10 and 9 may be the same).
Each OS makes its own decisions what to do with the priorities, as Java is using the underlying OS's threading mechanism.
Be sure to read the next article after that, which shows you how it's done on Linux and Windows.
I think your problem may stem from the third point above (if you're running on Windows), but it may be any of the other reasons.
If you need to execute threads with exact order, you can't do this with thread priority. You can use to one of the synchronization supports. (e.g Locks, semaphores).
I think the proper answer is: You cannot reliably order thread start by setting thread priority.
I think your confusion stems from the fact that the documentation states
Threads with higher priority are executed in preference to threads
with lower priority.
While this is true, it only refers to threads that are doing computation (or, on some operating systems, waiting for a shared resource). In such cases, threads with higher priority will receive more CPU time, i.e. will be executed in preference to threads that compete for the same resource.
Even if the thread priority would influence the order in which your threads are started (it most likely doesn't), all your threads could actually really run in parallel on modern CPUs as they don't influence each other.
In fact, the order of execution is determined by some other factor entirely: The threads don't do any relevant computation, they spent most of their (really small) execution time waiting for a shared resource, namely System.out.
One has to look at the code to find that the code underlying System.out, which is PrintStream actually does atomic, synchronized writes:
public void write(byte buf[], int off, int len) {
try {
synchronized (this) {
ensureOpen();
out.write(buf, off, len);
if (autoFlush)
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
So what happens is that the first thread that reaches the println() blocks all other threads until it is done with writing its output. First thread winds regardless of priority because you cannot interrupt a synchronized block (that would defeat the purpose of the monitor).
Which thread gets the lock first depends on more factors than just thread priority and maybe even not on the (Java) thread priority at all.
I'm running a multi threaded program and the problem I have is that it produces different output each time it's run. Here's my code.
package com.mypackage;
public class TryThreads extends Thread{
int i=-10;
public static void main(String arg[]){
TryThreads tt1=new TryThreads();
TryThreads tt2=new TryThreads();
tt1.start();
tt2.start();
}
public synchronized void run() {
for(;i<=10;i++) {
System.out.println(TryThreads.getThreadName()+" "+i);
}
}
static String getThreadName() {
Thread t1=new Thread();
return t1.getName();
}
}
whenever I run the code it produces different output, can anybody help me out with this?
Let's sum up you code:
You are starting two threads.
Your threads loop from i = -10 to 10
Each loop calls a static method.
The static method creates a NEW thread each time and returns the
name of the NEW thread.
The caller thread outputs the name of each NEW thread plus the index
variable i.
When you are running your code you are going to create 2 + 42 Threads (index 0 to 43).
First thing that makes no sense is that you are synchronizing the run() method which is useless because both of the two threads are working on their own object. The different output is as expected because you cannot predict when one of the two threads is active and iterating over the static getThreadName() method. It could be that Thread1 is doing 3 iterations before Thread2 is doing one. But it could also be that Thread2 is doing five iterations before Thread1 makes one.
This behaviour is called race confitions. It is up to the VM/OS to handle the threads if you don't manage them in you application code.
It is normal but if you do:
public static void main(String arg[]){
TryThreads tt1=new TryThreads();
TryThreads tt2=new TryThreads();
tt1.start();
tt2.start();
tt1.join();
tt2.join();
}
Then you should get first thread 1 name and then thread 2 name. It is normal that you get different results. Usually you store thread results in for example different class variable making sure that everything is thread safe. For example making method that is writing data to some variable synchronized. There is many ways to do it. But in your case you get that result cause you do not join threads to the main thread. It would be more noticeable if you spawn more threads doing much more than printing thread name.
Here is nice article about threads -> THREADS
But if you actually ask why your threads name are different then it is normal they are generated when you create new thread...
I have a loop that doing this:
WorkTask wt = new WorkTask();
wt.count = count;
Thread a = new Thread(wt);
a.start();
When the workTask is run, the count will wt++ ,
but the WorkTask doesn't seems change the count number, and between the thread, the variable can't share within two thread, what did I wrote wrong? Thanks.
Without seeing the code for WorkThread it's hard to pin down the problem, but most likely you are missing synchronization between the two threads.
Whenever you start a thread, there are no guarantees on whether the original thread or the newly created thread runs first, or how they are scheduled. The JVM/operating system could choose to run the original thread to completion and then start running the newly created thread, run the newly created thread to completion and then switch back to the original thread, or anything in between.
In order to control how the threads run, you have to synchronize them explicitly. There are several ways to control the interaction between threads - certainly too much to describe in a single answer. I would recommend the concurrency trail of the Java tutorials for a broad overview, but in your specific case the synchronization mechanisms to get you started will probably be Thread.join and the synchronized keyword (one specific use of this keyword is described in the Java tutorials).
Make the count variable static (it looks like each thread has its own version of the variable right now) and use a mutex to make it thread safe (ie use the synchronized instruction)
From your description I came up with the following to demonstrate what I perceived as your issue. This code, should output 42. But it outputs 41.
public class Test {
static class WorkTask implements Runnable {
static int count;
#Override
public void run() {
count++;
}
}
public static void main(String... args) throws Exception {
WorkTask wt = new WorkTask();
wt.count = 41;
Thread a = new Thread(wt);
a.start();
System.out.println(wt.count);
}
}
The problem is due to the print statement running before thread had a chance to start.
To cause the current thread ( the thread that is going to read variable count ) to wait until the thread finishes, add the following after starting thre thread.
a.join();
If you are wishing to get a result back from a thread, I would recommend you to use Callable
interface and an ExecutorSercive to submit it. e.g:
Future future = Executors.newCachedThreadPool().submit
(new Callable<Interger>()
{
int count = 1000;
#Override public Integer call() throws Exception
{
//here goes the operations you want to be executed concurrently.
return count + 1; //Or whatever the result is.
}
}
//Here goes the operations you need before the other thread is done.
System.out.println(future.get()); //Here you will retrieve the result from
//the other thread. if the result is not ready yet, the main thread
//(current thread) will wait for it to finish.
this way you don't have to deal with the synchronization problems and etc.
you can see further about this in Java documentations:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html
Why would the compiler print 2 a and then 2 b or vice versa when giving the priority to Thread a to start? Shouldn't thread b wait for thread a to finish in order to start? Can someone please explain how does it work?
public class Test1 extends Thread{
static int x = 0;
String name;
Test1(String n) {
name = n;
}
public void increment() {
x = x+1;
System.out.println(x + " " + name);
}
public void run() {
this.increment();
}
}
public class Main {
public static void main(String args[]) {
Test1 a = new Test1("a");
Test1 b = new Test1("b");
a.setPriority(3);
b.setPriority(2);
a.start();
b.start();
}
}
Giving priorities is not a job for the compiler. It is the OS scheduler to schedule and give CPU time (called quantum) to threads.
The scheduler further tries to run as much threads at once as possible, based on the available number of CPUs. In today's multicore systems, more often than not more than one core are available.
If you want for a thread to wait for another one, use some synchronizing mechanism.
Shouldn't thread b wait for thread a to finish in order to start?
No. The priority does not block the thread execution. It only tells the JVM to execute the thread "in preference to threads with lower priority". This does imply a wait.
Since your code is so trivial, there is nothing to wait for. Any of the two threads is run.
Why would the compiler print 2 a and then 2 b?
Luck of the draw. "Priority" means different things on different operating systems, but in general, it's always part of how the OS decides which thread gets to run and which one must wait when there's not enough CPUs available to run them both at the same time. If you computer has two or more idle CPUs when you start that program, then everybody gets to run. Priority doesn't matter in that case, and its just a race to see which one gets to the println(...) call first.
The a thread in your example has an advantage because the program doesn't call b.start() until after the a.start() method returns, but how big that advantage actually is depends on the details of the OS thread scheduling algorithm. The a thread could get a huge head start (like, it actually finishes before b even starts), or it could be a near-trivial head start.