最近看了一个老哥的博文,发现Thread.join()的例子中每次执行结果都不一样,特把例子贴出来:
/**
* Copyright (C), 2002-2012, www.chinarainbow.com.cn
* @{#} JoinThread.java Create on 2011-6-9 下午02:05:59
* @author 米饭超人
* @version 1.0
* @description 类说明
*
* History
* Date: 2011-6-9
* @author
* @modification: 初始版本
*/
package org.threads;
import java.util.concurrent.atomic.*;
public class JoinThread extends Thread {
private static int n = 0;
private static AtomicInteger sum=new AtomicInteger();
public void run() {
for (int i = 0; i < 10; i++)
try {
addN();
sleep(3); // 为了使运行结果更随机,延迟3毫秒
} catch (Exception e) {
e.printStackTrace();
}
}
private synchronized void addN() {
// sum.incrementAndGet();
n++;
}
public static void main(String[] args) throws Exception {
Thread threads[] = new Thread[100];
for (int i = 0; i < threads.length; i++) {
threads[i] = new JoinThread();
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
System.out.println(threads.length);
// if (args.length > 0) {
for (int i = 0; i < threads.length; i++) {
// 100个线程都执行完后继续
threads[i].join();
}
// }
System.out.println("n=" + JoinThread.n);
System.out.println("AtomicInteger=" + sum.get());
}
}
这个例子的结果是 "n" 有时候不是1000. 很长一段时间一直找不到原因,今天终于弄明白了。
问题在这里:
private synchronized void addN()
如果这里不用静态,那么每次执行结果是不一样的,如果修改成静态方法就可以,那这又是为什么呢?静态方法和变量是分配到stack里,内存固定,非静态是分配到heap里,即静态是全局和唯一的,那么加上synchronized 就能保证计数器正确!相反,非全局唯一,及时加入synchronized ,是非单例模式,所以不是同步的。可能heap有多个地址,只是值一样而已。所以最好用静态方法调用静态变量更稳妥些!