2017-07-19 130 views
0
public class TestThread2 { 

    static int count = 0; 
    public static void main(String[] args) { 

     Thread t = new Thread(new Runnable(){ 
      public void run() 
      { 
       for (int i=1; i<=100000; i++) { 
        count++; 
       }   
      } 
     }); 
     Thread t1 = new Thread(new Runnable(){ 
      public void run() 
      { 
       for (int i=1; i<=100000; i++) { 
        count++; 
       }   
      } 
     }); 
     t.start(); 
     t1.start(); 

     try{ 
      t.join(); 
      t1.join(); 
     } 
     catch(InterruptedException e){ 
      e.printStackTrace(); 
     } 

     System.out.println(count); 
    } 
} 

上面的代码打印数量,如131938的各种价值观,127518等加入,但我认为它应该总是打印20000加入为后()被调用,主线程不能移到下一个语句,直到当前线程死亡。我知道我在这里错过了一个基本概念,但我无法弄清楚,所以请帮助。Java线程有两个线程和静态变量

+1

'我++'不是原子的。这是Java并发101;去实践中阅读Java Concurrency。 –

+0

通常,您会在[CountDownLatch](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html)中调用'await()',并从2开始,当每个线程完成时(最终阻止)'countDown()' –

+0

没有多大关系,但为了得到相同的答案,您始终可以设置关联并仅使用一个核心。然后你总是会得到相同的答案。 –

回答

2

i++不是原子的。这是有效的:

int j = i; 
i = j + 1; 

如果两个线程都试图在同一时间做这一点,读取和来自不同线程写入可能交错,这意味着该值不严格每个线程递增。

此外,不能保证一个线程的增加值对另一个线程是可见的。

而不是使用int,请使用AtomicIntegeraddAndGetAtomicInteger保证增量的原子性和线程之间的值的可见性。

static AtomicInteger count = new AtomicInteger(); 

// In the thread: 
count.incrementAndGet(); 

注意的东西非常相似,你的例子在the Oracle Java Tutorial描述。

2

您不同步变量。而不是static int count,请使用AtomicInteger

1

是主线程块上01​​。但主线程不会写入变量count,所以主线程在做什么并不重要。您有2个线程,tt1,它们在没有任何同步的情况下读取和写入相同的变量count,实际上它会导致不稳定的结果。