Reputation: 562
I have decided to face this monster called concurrency and broaden my threading knowledge, so before I read through Joshua Bloch's book, I decided to code something random to help me understand the problem I might face before reading the book, hopefully I can then come to my code and make corrections but then I landed into this pit and I am hoping someone can explain.
I have the following:
public class Arithmetic implements Runnable {
int number;
public Arithmetic(int x){
this.number = number + x;
}
@Override
public void run() {
Thread.currentThread().setName("thread-"+number +" > " + "number = "+getNumber());
System.out.println(Thread.currentThread().getName());
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = getNumber() + number;
}
}
Then a main class:
public class Main {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
for (int x=0; x<=5; x++){
Thread thread = new Thread(new Arithmetic(x));
thread.start();
}
}
}
With this I get the following as output:
run:
main
thread-0 > number = 0
thread-1 > number = 1
thread-2 > number = 2
thread-3 > number = 3
thread-5 > number = 5
thread-4 > number = 4
Notice: The 5 comes before 4
But then I change my main class to:
public class Main {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
for (int x=0; x<=5; x++){
Runnable runnable = new Arithmetic(x);
runnable.run();
}
}
}
I get the output below:
run:
main
thread-0 > number = 0
thread-1 > number = 1
thread-2 > number = 2
thread-3 > number = 3
thread-4 > number = 4
thread-5 > number = 5
Notice: Correct sequence
I was hoping both main(s) will produce erratic result(Like Thread implementation), then I would then use some thread safety measures like synchronised access etc. but why does the Runnable call act as if Arithmetic
is thread safe?
IMO, the difference between extending Thread class and implementing Runnable is for decoupling purposes. Apologies if this is a duplicate question, I can't seem to find an answer.
Thanks in advance.
Upvotes: 0
Views: 1475
Reputation: 425448
Your Runnables are all executing in the main thread (and in that code there is only the one "main" thread).
Your threads all execute separately, and java give no guarantee that once started threads will execute in any particular order.
Upvotes: 1
Reputation: 5419
Because Runnable
itself doesn't run on a seperate thread. It is just an interface used for passing a method implementation around. One example of such is passing it to a Thread
constructor (as you have done in your first example). Thus in your second example, nothing is being executed concurrently; it's just executing the run()
methods one after the other.
Upvotes: 0
Reputation: 31754
The thing is when you do
Thread t = new Thread(new Arithemetic())
t.start();
The thread t
is started and it executed Arithmetic
.
In your case you are calling runnable.run();
, which means the current thread shall call code inside your run()
. It is similar to calling any other method.
Ultimately, your current thread in itself is executing the run
method 5 times
Upvotes: 2
Reputation: 30042
Runnables
do not start new threads it is simply and interface, so this means your second piece of code runs synchronously.
Threads
are new threads so you they can run in parallel, which is why the output comes out of order - the 4th thread executes slower than the 5th.
Upvotes: 3