单独的线程可以更改静态变量吗?

时间:2017-07-17 12:43:11

标签: java multithreading static

浏览网页后,我仍然对以下线程行为感到困惑。我知道静态变量在同一个类加载器中共享,但是在这个提取中肯定没有:

public class parallelCounter {
    public static final int N = 100000000;
    public static int j = 0;
    public static void inc() {
        for (int i = 0; i < N; i++) {
            j++;
        }
        System.out.println(j); // 10000000
    }
}

class parallelCounterDemo {
    public static void main(String[] args) {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                parallelCounter.inc();
            }
        });
        t1.start();
        System.out.println(parallelCounter.j); // 0 Why?
    }
}

5 个答案:

答案 0 :(得分:1)

这里有两点需要注意:

  1. 您的代码具有竞争条件,因为打印时的状态取决于两个独立线程的执行速度。 @media print { … } 执行t1时,大多数时间inc都不会开始执行println。您可以尝试在sleep(100)之后添加t1.start或其他内容。

  2. 您必须注意,并非所有对一个线程所做变量的更改都会立即被其他线程看到 - 这是一个非常复杂的主题,您必须检查哪些构造将导致线程之间的数据同步。对于您的示例,最简单的方法是将j声明为public static volatile int

答案 1 :(得分:1)

在当前状态下,您的代码存在并发问题,因为两个线程同时尝试访问静态int变量(不同步):

  • Main Thread尝试读取变量的值
  • t1 Thread尝试写入变量的值

Syso输出0,因为t1线程的run方法尚未开始(没有进行增量)。但这并不是100%保证会一直发生。

如果你想确保t1线程在main中执行Syso之前完成执行,你应该使用join方法:

public class parallelCounter {
    public static final int N = 100000000;
    public static int j = 0;
    public static void inc() {
        for (int i = 0; i < N; i++) {
            j++;
        }
        System.out.println(j); // 10000000
    }
}

class parallelCounterDemo {
    public static void main(String[] args) {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                parallelCounter.inc();
            }
        });
        t1.start();
        try {
            t1.join(); // Wait for thread to finish
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(parallelCounter.j);
    }
}

答案 2 :(得分:0)

t1是一个新的线程,它启动异步,你的代码继续而不调用inc()函数,所以j数字仍为0

答案 3 :(得分:0)

当您致电System.out.println(parallelCounter.j);时,您帖子中的parallelCounter.inc();功能仍然没有结束。因此,j的值仍然未增加,为0.将for循环替换为简单分配,并在启动Thread.sleep(1000);后添加Thread t1,并且你会得到理想的行为。

答案 4 :(得分:0)

我没有运行你的代码,但我假设方法调用 rule "Add validation error for policies with requested covers that are not available" when $p: Policy(available == true, $requestedCovers: requestedCovers, $covers: covers) $requestedCover: String() from $requestedCovers Cover(type not contains $requestedCover) from $covers then log.error("RHS rule not implemented yet. Found type {}.", $requestedCover); end 很快就会在程序的执行流程中出现。

您启动了该主题,然后您的代码立即打印了System.out.println(parallelCounter.j);的值。 我认为该线程没有足够的时间来启动run()方法。

我建议您在打印j之前插入一些等待时间,例如

j