java thread start方法或方法

时间:2014-10-30 02:31:06

标签: java multithreading

此代码来自样本OCP / SCJP

我不确定为什么在run()之前调用Printx()。 为什么这有保证?

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();

    }

}

2 个答案:

答案 0 :(得分:4)

我不认为'保证'在这里是正确的词。实际上,printx可能会先完成,因为starting a new thread takes a huge amount of time相对于当前运行的线程执行litle算术所花费的时间,获得控制台的(无竞争)锁并写入它。

但这是一种竞争条件,依靠先发生的事情是一个非常糟糕的主意。如果程序运行足够多次,则可能发生各种交错。这里不能保证会发生什么事情,最好避免做出假设。

还有另一个问题。构造函数由主线程调用,初始化x,然后启动新线程。新线程在run方法中修改x,但是没有任何要求使新内容对x的内容可见。制作x volatile会使其内容可见。

另一个问题是:算术运算需要执行多个步骤,并且可能受到另一个线程的干扰。这不仅仅是一个操作首先会发生的问题,它们可能是交错的。修复此问题需要锁定或使用atomicInteger。

答案 1 :(得分:3)

ConstructorOrRun()立即在主线程上返回,然后调用printX()。

在构造函数返回之前,无法保证在构造函数中调用start()会导致run()启动,更不用说完成(在不同的线程上)。事实上,如果确实如此,我会感到惊讶。