Java Thread连接有两个线程和一个静态变量

时间:2017-07-19 12:08:16

标签: java multithreading static

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,因为在调用join()之后,主线程无法移动到下一个语句,直到当前线程死亡。我知道我在这里错过了一个基本概念,但我无法弄清楚所以请帮忙。

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分: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 :(得分:1)

join()上的主要线程阻止。但是主线程没有写入变量count,因此主线程正在做什么并不重要。您有2个线程tt1,它们在没有任何同步的情况下读取和写入相同的变量count,实际上它会导致不稳定的结果。