JAVA中增强循环中用线程,Java for循环中是否有针对线程安全性的优化?

I have a snippet of code that change a counter in two threads. It's not thread safe because I didn't put any atomic variable or lock in the code. It gives the right result as I expected if the code only run once, but I want to run it for several times, so I put the code into a for loop. And the question is that only the first or the first two loops will generate the result I expect. For the rest of the loops, the results are always 0, which seems to be thread safe. Is there any inner operator in Java Virtual Machine resulting such thing?

I have tried change the number of loops, and the first one or two are always what I expect, but the others are 0 no matter how many loops there are.

Counter:

private static class Counter {

private int count;

public void increase() {

count++;

}

public void decrease() {

count--;

}

public int getCount() {

return count;

}

}

Person:

// This is just a thread to increase and decrease the counter for many times.

private static class Person extends Thread {

private Counter c;

public Person(Counter c) {

this.c = c;

}

@Override

public void run() {

for (int i = 0; i < 100000; i++) {

c.increase();

c.decrease();

}

}

}

Main method:

public static void main(String[] args) throws InterruptedException {

for (int i = 0; i < 10; i++) {

Counter c = new Counter();

Person p1 = new Person(c);

Person p2 = new Person(c);

p1.start();

p2.start();

p1.join();

p2.join();

System.out.println("run "+i+": "+c.getCount());

}

}

Output:

run 0: 243

run 1: 12

run 2: 0

run 3: 0

run 4: 0

run 5: 0

run 6: 0

run 7: 0

run 8: 0

run 9: 0

I don't know why the rest of the results are always 0. But I guess it's about the optimization of JVM. Is it right that the JVM optimizes the code when some loops have been done, and it omits the rest loops and always gives 0 as answer?

解决方案

I think the JVM is optimizing here like you said.

I added some outputs with timings to your question, which clearly show, that optimization happens there.

public static void main(String[] args) throws InterruptedException {

for (int i = 0; i < 10; i++) {

final long startTime = System.currentTimeMillis();

Counter c = new Counter();

Person p1 = new Person(c);

Person p2 = new Person(c);

p1.start();

p2.start();

p1.join();

p2.join();

final long endTime = System.currentTimeMillis();

System.out.println(String.format("run %s: %s (%s ms)", i, c.getCount(), endTime - startTime));

}

}

Results:

run 0: 1107 (8 ms)

run 1: 1 (1 ms)

run 2: 0 (2 ms)

run 3: 0 (0 ms)

run 4: 0 (0 ms)

run 5: 0 (0 ms)

run 6: 0 (1 ms)

run 7: 0 (0 ms)

run 8: 0 (0 ms)

run 9: 0 (0 ms)

The first iterations the program needs a lot of time, wheras in later execution nearly no time at all is used.

Seems to be legit to suspect optimazation for this behaviour.

Using a volatile int count:

run 0: 8680 (15 ms)

run 1: 6943 (12 ms)

run 2: 446 (7 ms)

run 3: -398 (7 ms)

run 4: 431 (8 ms)

run 5: -5489 (6 ms)

run 6: 237 (7 ms)

run 7: 122 (7 ms)

run 8: -87 (7 ms)

run 9: 112 (7 ms)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值