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...
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'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.
Why does the below program output 11 and not 12?.
Does not the thread use the same instance variables? Please explain?
public class Tester extends Thread {
private int i;
public static void main(String[] args){
Tester t = new Tester();
t.run();
System.out.print(t.i);
t.start();
System.out.print(t.i);
}
public void run(){ i++;}
}
The above code compiles fine. i is defaulted to 0 value on construction of object.
In happens before relation concept all code executed prior to start of thread is completed.
The concept is - instance variables are shared across multiple threads - here there are two threads running - the main thread and the Tester thread. So i should shared with both threads? - if i is shared and if happens-before relation is maintained before starting Tester thread then the value of incremented i should be visible to the Tester thread?
Give to your new thread the time to increase the variable, try with
public static void main(String[] args){
Tester t = new Tester();
t.run();
System.out.println(t.i);
t.start();
try {
Thread.sleep(1000); // 1 sec
} catch (Exception ex) {}
System.out.println(t.i);
}
The only problem in your code is that you print the t.i value and do not wait after t.start(), you print the value before the thread increases it.
The instance variable can be accessed by multiple threads if you let them, for example making it public, or by any other means.
In your code this is what happens: The Tester thread t will access it's own variable, and you will access also that same variable from the main thread. For the moment when you ask it to print the value, it may print any value by which the Testet thread t is at the moment.
When the main thread calls the run method it will execute in the main thread, effectively increasing the value of the field to 1 (as 0 is the default). Afterwards when you call the method start it will start the separate thread and the Java VM will call the method run, then again the field gets incremented, this time from 1 to 2.
So, I would expect that the output is 1 and then, possible 1 or possibly 2 depending on whatever there was time for the thread to execute before you asked to print the value from the main thread.... the exact result you get depends on your machine, in another computer it can be another tale. This depends on the CPU, the operating system, the available memory and other things.
As dash1e suggested in his answer, you can use Thread.sleep(1000); to make the main thread wait while the Tester thread t executes on background. This greatly increases the likelihood that the Tester thread t will have updated the value of the field before the main thread asks for it to print it. That said, I want to left clear that using Thread.sleep(1000); to wait for a task to complete is not good enough by itself... if you want to, you can put a call to Thread.sleep inside a while where you verify if a certain criteria has been met, that's known as an spinning.
The fact that you can print the value of the field form the main thread demostrates that you can access it from another thread. And that is a good thing, because you want your thread to communicate... somehow.
It is ok to access it because it is only an int, and an int cannot be in an invalid state, so there is no need sync the access. Although you may get an not up-to-date value, and it will change on background, so it isn't very reliable.
If you want a value that can only be acceded by a single thread, and that exists idependly for each thread, then take a look to ThreadLocal.
The main answer that I was looking for was in terms of happens-before: Concept detailed below:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility
So it says in the docs -
a) that before a thread starts - all statements prior to it are completed
b) all statements in the thread execution are completed at the termination of the new thread.
Going with the above understanding - i should be all the time visible to the new thread started. And this it should be - at all times, on all systems - so when start is called and a new thread is launched then it should always see i as 1.
But, the time we are printing the i value is getting executed by the main thread - not by the Tester thread. So even though the new Tester thread may see the value as 1 and increment it as 2 - the execution in main does not reflect it because i++ is not an atomic operation.
Now suppose we try and make the int as :
private volatile int i;
volatile guarantees happens-before relationship for not only the specific variable but also statement until it.
The println of main thread that gets executed may get executed before the increment even began. So we may see 11 getting printed, even after making the variable volatile. Similar case exists for making the variable an AtomicInteger.
The run method when invoked will see the incremented value:
System.out.println("i "+ i.incrementAndGet());
But not the main thread. Visibility of data in the run method / main method differs.
Instance variable used is same for both threads executing.
You have started the thread, but have not wait for it to stop. Use t.join() to wait for finish. And, yes, you have thread synchronization issue, but that's another issue.
public class Tester extends Thread {
private int i;
public static void main(String[] args) throws InterruptedException {
Tester t = new Tester();
t.run();
System.out.println(t.i);
t.start();
t.join();
System.out.println(t.i);
}
public void run() {
i++;
}
}
I your code:
public class Tester extends Thread {
private int i;
public static void main(String[] args){
Tester t = new Tester();
t.run();
System.out.print(t.i);
t.start();
System.out.print(t.i);
}
public void run(){ i++;}
}
You call t.run() and t.start(). There are 2 thread are running t.run() thread and t.start() thread.
In that i variable you share between 2 thread that is not synchronous.
Therefore sometime value of i variable is not update between threads.
You can synchronous by using volatile keyword
private volatile int i;
Or synchronise code segment increases value of i
public void run(){
synchronized(this){
i++;
}
}
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.