Java 线程应该在我使用构造函数中的start()创建对象后开始运行

Java 线程应该在我使用构造函数中的start()创建对象后开始运行,java,multithreading,Java,Multithreading,我使用了两个类 头等舱:柜台 public class Counter { int val = 0; void inc() { val++;} void dcr() { val--;} } 第二类:螺纹测试 public class ThreadTesting extends Thread { /** * @param args the command line arguments */ Counter c; ThreadTesting(Counter c){ this.c =

我使用了两个类

头等舱:柜台

public class Counter {
int val = 0;
void inc() { val++;}
void dcr() { val--;}
}
第二类:螺纹测试

public class ThreadTesting extends Thread {

/**
 * @param args the command line arguments
 */
Counter c;
ThreadTesting(Counter c){
    this.c = c;
    start();
}

public void run(){
    for(int i=0;i<10000;i++)
        c.dcr();
}
public static void main(String[] args) throws Exception {
    // TODO code application logic here
    Counter c = new Counter();
    ThreadTesting rc = new ThreadTesting(c);
    Boolean stateOfThread = rc.isAlive();
    System.out.println(stateOfThread);
    for(int i=0;i<10000;i++)
       c.inc();
    rc.join();

    System.out.println("Final value of c.val: "+c.val);
}

}
公共类线程测试扩展了线程{
/**
*@param指定命令行参数
*/
计数器c;
螺纹测试(计数器c){
这个.c=c;
start();
}
公开募捐{

对于(int i=0;i如果您对上述语句进行注释,则构造函数仍将启动第二个线程,但
System.out.println(“c.val的最终值:”+c.val);
在第二个线程的
run()之前在主线程上执行
方法启动。因此打印输出时,
c.val
仍为
0

在print语句之前添加一个
线程。sleep(1000)
,您将看到第二个线程正在运行

您很可能会得到以下输出:

Final value of c.val: -10000

注意:在构造函数中启动线程是一个糟糕的想法。问题不是线程没有启动,而是其他线程看不到对变量的更新。使
val
易失性
(或者只使用
原子整数
).@AndyTurner很可能在线程有机会更新变量之前打印。但即使这样,值也可能是0,因为您忽略了
连接
。下次,请只发布您要发布的代码,而不是无关的代码。如果您在注释掉所显示的一大块代码时问为什么得到0,请根本不要显示该代码。
-10000
不能保证,理论上,由于可见性和调度,他可以获得任何输出。@Oleg在这个简单的程序中,极有可能在睡眠期结束后主线程恢复执行时,第二个线程的执行将完成。@t.J.Crowder jls中没有任何保证这
System.out.println(“c.val的最终值:+c.val”)
将从另一个线程看到对
c.val
的更新,即使它完成了执行。A发生在需要建立关系之前,但在这种情况下不是这样。@Oleg:我相信你的理论。我很难相信实践中引用的带有Eran一秒钟睡眠的代码永远不会显示-10000。但我确信你是对的,如果把一个孤立的案例推广到一个理论很可能会出现并伤害你的情况,那将是危险的。:-)
Final value of c.val: -10000