浏览网页后,我仍然对以下线程行为感到困惑。我知道静态变量在同一个类加载器中共享,但是在这个提取中肯定没有:
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?
}
}
答案 0 :(得分:1)
这里有两点需要注意:
您的代码具有竞争条件,因为打印时的状态取决于两个独立线程的执行速度。 @media print {
…
}
执行t1
时,大多数时间inc
都不会开始执行println
。您可以尝试在sleep(100)
之后添加t1.start
或其他内容。
您必须注意,并非所有对一个线程所做变量的更改都会立即被其他线程看到 - 这是一个非常复杂的主题,您必须检查哪些构造将导致线程之间的数据同步。对于您的示例,最简单的方法是将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