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

标签 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);
    }
}

上面的代码打印了 count 的各种值,例如 131938、127518 等。但我认为它应该始终打印 20000,因为在调用 join() 后,主线程无法移动到下一个语句,直到当前线程死亡。我知道我在这里缺少一个基本概念,但我无法弄清楚,所以请帮助。

最佳答案

i++ 不是原子的。它有效地:

int j = i;
i = j + 1;

如果两个线程尝试同时执行此操作,则来自不同线程的读取和写入可能会交错,这意味着每个线程中的值不会严格递增。

此外,无法保证一个线程增加的值对另一个线程可见。

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

static AtomicInteger count = new AtomicInteger();

// In the thread:
count.incrementAndGet();
<小时/>

请注意,the Oracle Java Tutorial 中描述了与您的示例非常相似的内容。 .

关于Java Thread 连接两个线程和一个静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45190096/

相关文章:

asp.net-mvc - 在 Action 内的单独线程上运行方法

python : threads do not work properly in daemon

c++ - 包含 std::string 常量的类

Java Applet/Javascript - 通过网络打印 pdf 时如何操作打印设置?

java - 正则表达式:匹配通配符后跟可变长度的数字

java - 自动生成站点地图

PHP:for循环内的静态变量和for循环外的非静态变量有什么区别?

java - org.jclouds.openstack.nova.v2_0.domain.ServerCreated API

Java线程生产者消费者程序

c - printf 是 C 中的静态函数吗?