2017-08-10 19 views
0

即使在调用run()2次后,为什么我的计数还没有增加?为什么即使在调用run()2次后,我的计数也不会增加?

public class Test extends Thread{ 
    private int i;//default value is 0 

    public void run(){ 
     i++;//increas value of i by 1 

    } 

    public static void main(String[] args){ 
     Test a = new Test(); 
     System.out.println(a.i); // prints 0 
     a.run();//direct call 
     System.out.println(a.i);// prints 1 
     a.start();// calls run() 
     System.out.println(a.i);// again prints 1 
    } 
} 
+2

@Tacolibre'Test extends Thread' – QBrute

+0

您只能调用'run()'一次。 –

+5

也许最后一个'println'发生在线程启动之前。 –

回答

1

如果您想在处理最终结果之前等待线程完成,您需要使用join方法。

捕获或抛出相应的异常。我只是把它扔在这种情况下。

public class Test extends Thread{ 
    private int i;//default value is 0 

    public void run(){ 
     i++;//increas value of i by 1 

    } 

    public static void main(String[] args) throws InterruptedException { 
     Test a = new Test(); 
     System.out.println(a.i); // prints 0 
     a.run();//direct call 
     System.out.println(a.i);// prints 1 
     a.start();// calls run() 

     a.join(); //Wait for the thread to finish 

     System.out.println(a.i);// again prints 2 
    } 
} 
+1

明白了。非常感谢。 :) –

+1

值得一提的是,在一个线程上执行运行并不是它要使用的方式。另外,连接的另一种方法是使用并发实用程序作为CountDownLatch,它还提供其他功能,如配置等待的最长时间,而不是永久。 –

4

您只能拨打run()一次。

当您致电start()时,它会启动另一个稍后运行的线程。在这种情况下,您的main很可能已经完成很长时间。

启动一个线程既不是同步的,也不是瞬时的,否则使用一个线程就没有意义。

0

您运行两个线程separatly第一个比第二的那么快,当第一个线程完成其打印1,然后启动线程2只后,你做一个打印的,你看到两个时间1 ,了解越多,你可以做这样的睡眠:

public static void main(String[] args) throws InterruptedException { 
    Test a = new Test(); 
    System.out.println(a.i); 
    a.run();//direct call 
    System.out.println(a.i); 
    a.start();// calls run() 
    Thread.sleep(1000);//<<----------------------------------Sleep a while 
    System.out.println(a.i); 
} 

在这种情况下,你会看到:

0 
1 
2 
+1

谢谢@YCF_L :) –

0

当你打电话“开始”的线程在开始 背景。这个调用按定义是异步的。所以你不能授予(它们是你编写它的方式)在线程的run方法结束之后最后一次打印将被执行。这是线程的关键。

如果您直接执行运行,那么您没有使用该线程,那不是异步。你只是直接执行方法实现。线程并不意味着以这种方式使用。

0

a.run()是一个阻塞呼叫。
仅当run()已终止其执行时才返回。
所以你一定会看到i被递增。

a.start()将调用run(),但在返回run()之前可能会返回。
所以你不一定会看到i被递增。

+0

当你谈论一个方法调用时,使用“阻塞”这个词有点奇怪。 – Gray

0

为什么即使在调用run()2次后,i的计数也不会增加?

正如其他人所提到的,主要的问题是,如果当前正在运行的线程调用run()方法直接,i将会立即更新。如果您致电start(),没有任何事情可以保证在到达System.out.println(...)行之前后台线程将调用run()

同样重要的是要认识到,即使线程确实调用run()方法,没有什么能确保主线程会真正看到i更新值。 a.join();不仅等待后台线程完成,而且还确保主线程看到该线程所做的任何内存更改。

线程之间共享的任何数据都需要标记为volatile或以其他方式同步以确保正确共享和更改可见性。

Test a = new Test(); 
System.out.println(a.i); // prints 0 
a.run(); //direct call, i updated in this thread 
System.out.println(a.i); // prints 1 
a.start(); // starts the process of creating a new thread, run() called in the future 
a.join(); // ensure that the background thread calls run() _and_ value of i is updated 
System.out.println(a.i); // now prints 2 
相关问题