Reputation: 155
This code came from sample OCP/SCJP
I'm not really sure why Printx() is called before run(). and why this is guaranteed?
public class ConstructorOrRun extends Thread {
private int x = 2;
public ConstructorOrRun() throws Exception {
x = 5;
start();
}
public void printX() throws Exception {
x = x - 1;
System.out.print(x);
}
public void run() {
x *= 2;
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
new ConstructorOrRun().printX();
}
}
Upvotes: 0
Views: 61
Reputation: 96385
I don't think 'guaranteed' is the right word here. In practice the printx will be likely to finish first, because starting a new thread takes a huge amount of time relative to the time taken for the current running thread to do a litle arithmetic, get the (uncontended) lock for the console and write to it.
It is a race condition, though, and it would be a really bad idea to rely on either thing happening first. If a program runs enough times all kinds of interleavings may happen. There's no guarantee which thing will happen first here, it would be better to avoid making assumptions.
There's another issue. The constructor is called by the main thread, initializing x, then starting a new thread. The new thread modifies x in the run method, but there isn't anything requiring making the contents of x visible to the new thread. Making x volatile would make its contents visible.
And yet another issue: the arithmetic operations take multiple steps to be executed and can be interfered with by the other thread. It's not just a question of which operation will happen first, they could be interleaved. Fixing this would require locking or using atomicInteger.
Upvotes: 4
Reputation: 30088
ConstructorOrRun() returns immediately, on the main thread, and then printX() is invoked.
There's no guarantee that calling start() in the constructor will cause run() to start, let alone finish (on a different thread), before the constructor returns. In fact, I'd be surprised if it did.
Upvotes: 3