多线程静态变量累加求和 , 计算结果是对的,但是不明白为什么是对的.

package thread.worker;

/**
 * Created by huli3 on 2017/8/16.
 */
public class ExecutorTest {
    static int sum = 0;

    public static void main(String[] args) throws InterruptedException {
        ThreadGroup hl = new ThreadGroup("hl");
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(hl, new MyThread(hl));
            thread.start();
        }
        while (hl.activeCount() > 0) {
            Thread.currentThread().yield();
        }
        System.out.println(sum);
    }

    static class MyThread implements Runnable {
        ThreadGroup threadGroup;

        public MyThread(ThreadGroup threadGroup) {
            this.threadGroup = threadGroup;
        }

        public void run() {
            for (int j = 0; j < 4; j++) {
                sum++;
                System.out.println(threadGroup.activeCount() + " sum " + sum + "  and current thread is :" + "id:"+Thread.currentThread().getId());
            }
//            System.out.println(threadGroup.activeCount() + " sum " + sum + "  and current thread is :" + Thread.currentThread().getId());

        }
    }
}

因为你用了volatile 修饰变量啊,所以线程里的每次取值都是新的,但是你的System.out.println()打印比较低效,所以会有看起来乱的现象

 package thread.worker;

/**
 * Created by huli3 on 2017/8/16.
 */
public class ExecutorTest {
    volatile static int sum = 0;

    public static void main(String[] args) throws InterruptedException {
        ThreadGroup hl = new ThreadGroup("hl");
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(hl, new MyThread(hl));
            thread.start();
        }
        while (hl.activeCount() > 0) {
            Thread.currentThread().yield();
        }
        System.out.println(sum);
    }

    static class MyThread implements Runnable {
        ThreadGroup threadGroup;

        public MyThread(ThreadGroup threadGroup) {
            this.threadGroup = threadGroup;
        }

        public void run() {
            for (int j = 0; j < 4; j++) {
                sum++;
                System.out.println(threadGroup.activeCount() + " sum " + sum + "  and current thread is :" + "id:"+Thread.currentThread().getId());
            }
//            System.out.println(threadGroup.activeCount() + " sum " + sum + "  and current thread is :" + Thread.currentThread().getId());

        }
    }
}

其中一次的执行结果是这样的:

 D:\programing\dev\java\1.8.1\bin\java "-javaagent:D:\programing\IntelliJ IDEA 2017.1.5\lib\idea_rt.jar=65386:D:\programing\IntelliJ IDEA 2017.1.5\bin" -Dfile.encoding=UTF-8 -classpath D:\programing\dev\java\1.8.1\jre\lib\charsets.jar;D:\programing\dev\java\1.8.1\jre\lib\deploy.jar;D:\programing\dev\java\1.8.1\jre\lib\ext\access-bridge-64.jar;D:\programing\dev\java\1.8.1\jre\lib\ext\cldrdata.jar;D:\programing\dev\java\1.8.1\jre\lib\ext\dnsns.jar;D:\programing\dev\java\1.8.1\jre\lib\ext\jaccess.jar;D:\programing\dev\java\1.8.1\jre\lib\ext\jfxrt.jar;D:\programing\dev\java\1.8.1\jre\lib\ext\localedata.jar;D:\programing\dev\java\1.8.1\jre\lib\ext\nashorn.jar;D:\programing\dev\java\1.8.1\jre\lib\ext\sunec.jar;D:\programing\dev\java\1.8.1\jre\lib\ext\sunjce_provider.jar;D:\programing\dev\java\1.8.1\jre\lib\ext\sunmscapi.jar;D:\programing\dev\java\1.8.1\jre\lib\ext\sunpkcs11.jar;D:\programing\dev\java\1.8.1\jre\lib\ext\zipfs.jar;D:\programing\dev\java\1.8.1\jre\lib\javaws.jar;D:\programing\dev\java\1.8.1\jre\lib\jce.jar;D:\programing\dev\java\1.8.1\jre\lib\jfr.jar;D:\programing\dev\java\1.8.1\jre\lib\jfxswt.jar;D:\programing\dev\java\1.8.1\jre\lib\jsse.jar;D:\programing\dev\java\1.8.1\jre\lib\management-agent.jar;D:\programing\dev\java\1.8.1\jre\lib\plugin.jar;D:\programing\dev\java\1.8.1\jre\lib\resources.jar;D:\programing\dev\java\1.8.1\jre\lib\rt.jar;E:\repository\maven\jd\hl-learn-project\java\thread\target\classes thread.worker.ExecutorTest
4 sum 3  and current thread is :id:11
6 sum 5  and current thread is :id:11
6 sum 6  and current thread is :id:11
5 sum 4  and current thread is :id:14
5 sum 3  and current thread is :id:13
7 sum 10  and current thread is :id:13
4 sum 2  and current thread is :id:12
7 sum 11  and current thread is :id:13
8 sum 14  and current thread is :id:13
7 sum 9  and current thread is :id:14
7 sum 15  and current thread is :id:14
8 sum 16  and current thread is :id:14
6 sum 8  and current thread is :id:11
7 sum 17  and current thread is :id:17
7 sum 18  and current thread is :id:17
6 sum 7  and current thread is :id:15
7 sum 20  and current thread is :id:15
7 sum 19  and current thread is :id:17
7 sum 22  and current thread is :id:17
6 sum 23  and current thread is :id:18
6 sum 24  and current thread is :id:18
6 sum 25  and current thread is :id:18
6 sum 26  and current thread is :id:18
7 sum 12  and current thread is :id:16
5 sum 27  and current thread is :id:16
5 sum 29  and current thread is :id:16
5 sum 30  and current thread is :id:16
8 sum 14  and current thread is :id:12
5 sum 29  and current thread is :id:19
4 sum 32  and current thread is :id:19
4 sum 33  and current thread is :id:19
4 sum 34  and current thread is :id:19
7 sum 21  and current thread is :id:15
3 sum 35  and current thread is :id:15
4 sum 31  and current thread is :id:12
2 sum 36  and current thread is :id:12
1 sum 37  and current thread is :id:20
1 sum 38  and current thread is :id:20
1 sum 39  and current thread is :id:20
1 sum 40  and current thread is :id:20
40

Process finished with exit code 0

看来是为java 老司机呀 还在使用线程组 可以了解 了解线程池

因为并没有给线程加锁来进行同步
所以在sum++的时候未打印就会被其他线程抢走去执行

  public void run() {
            for (int j = 0; j < 4; j++) {
                System.out.println(threadGroup.activeCount() + " sumB:" + sum + "  and current thread is :" + "id:"+Thread.currentThread().getId());
                sum++;
                System.out.println(threadGroup.activeCount() + " sumE:" + sum + "  and current thread is :" + "id:"+Thread.currentThread().getId());
            }
            System.out.println("sum:"+sum+"Result:"+Thread.currentThread().getId());
//            System.out.println(threadGroup.activeCount() + " sum " + sum + "  and current thread is :" + Thread.currentThread().getId());

        }
 3 sumB:0  and current thread is :id:10
5 sumB:0  and current thread is :id:12
6 sumE:1  and current thread is :id:12
6 sumE:2  and current thread is :id:10
7 sumB:2  and current thread is :id:10
7 sumB:3  and current thread is :id:14
4 sumB:0  and current thread is :id:11
9 sumE:5  and current thread is :id:11
9 sumB:5  and current thread is :id:15
3 sumB:0  and current thread is :id:9
10 sumE:6  and current thread is :id:15
10 sumB:7  and current thread is :id:17
10 sumE:8  and current thread is :id:17
10 sumB:8  and current thread is :id:17
10 sumE:9  and current thread is :id:17
10 sumB:9  and current thread is :id:17
10 sumE:10  and current thread is :id:17
10 sumB:10  and current thread is :id:17
10 sumE:11  and current thread is :id:17
9 sumB:5  and current thread is :id:11
10 sumE:12  and current thread is :id:11
10 sumB:12  and current thread is :id:11
9 sumB:5  and current thread is :id:16
10 sumE:14  and current thread is :id:16
10 sumB:14  and current thread is :id:16
10 sumE:15  and current thread is :id:16
10 sumB:15  and current thread is :id:16
10 sumE:16  and current thread is :id:16
10 sumB:16  and current thread is :id:16
10 sumE:17  and current thread is :id:16
sum:17Result:16
8 sumE:4  and current thread is :id:14
9 sumB:17  and current thread is :id:14
9 sumE:18  and current thread is :id:14
9 sumB:18  and current thread is :id:14
9 sumE:19  and current thread is :id:14
9 sumB:19  and current thread is :id:14
9 sumE:20  and current thread is :id:14
sum:20Result:14
7 sumE:3  and current thread is :id:10
8 sumB:20  and current thread is :id:10
8 sumE:21  and current thread is :id:10
8 sumB:21  and current thread is :id:10
8 sumE:22  and current thread is :id:10
sum:22Result:10
6 sumB:2  and current thread is :id:12
6 sumB:1  and current thread is :id:13
7 sumE:23  and current thread is :id:12
7 sumB:24  and current thread is :id:12
7 sumE:25  and current thread is :id:12
7 sumB:25  and current thread is :id:12
7 sumE:26  and current thread is :id:12
sum:26Result:12
10 sumE:13  and current thread is :id:11
sum:11Result:17
10 sumB:8  and current thread is :id:18
10 sumB:7  and current thread is :id:15
5 sumE:28  and current thread is :id:15
5 sumB:28  and current thread is :id:15
5 sumE:29  and current thread is :id:15
5 sumB:29  and current thread is :id:15
5 sumE:30  and current thread is :id:15
sum:30Result:15
10 sumE:7  and current thread is :id:9
5 sumE:27  and current thread is :id:18
6 sumB:26  and current thread is :id:11
7 sumE:24  and current thread is :id:13
4 sumB:31  and current thread is :id:18
4 sumE:32  and current thread is :id:18
4 sumB:32  and current thread is :id:18
4 sumE:33  and current thread is :id:18
4 sumB:33  and current thread is :id:18
4 sumE:34  and current thread is :id:18
sum:34Result:18
4 sumE:31  and current thread is :id:11
sum:34Result:11
4 sumB:30  and current thread is :id:9
2 sumE:35  and current thread is :id:9
2 sumB:35  and current thread is :id:9
2 sumE:36  and current thread is :id:9
2 sumB:36  and current thread is :id:9
2 sumE:37  and current thread is :id:9
sum:37Result:9
4 sumB:31  and current thread is :id:13
1 sumE:38  and current thread is :id:13
1 sumB:38  and current thread is :id:13
1 sumE:39  and current thread is :id:13
1 sumB:39  and current thread is :id:13
1 sumE:40  and current thread is :id:13
sum:40Result:13
40

比如线程14在sum++前就读取到了sum为3
但是在之后才抢回并执行
因为多线程会都有共享变量的一个副本
所以之后打印的依然是4

去掉volatile关键字的结果如下:

3 sum 1 and current thread is :id:11
5 sum 2 and current thread is :id:13
6 sum 4 and current thread is :id:13
6 sum 5 and current thread is :id:13
6 sum 6 and current thread is :id:13
6 sum 7 and current thread is :id:12
5 sum 8 and current thread is :id:12
5 sum 3 and current thread is :id:11
6 sum 10 and current thread is :id:11
6 sum 11 and current thread is :id:11
6 sum 11 and current thread is :id:12
6 sum 13 and current thread is :id:15
6 sum 13 and current thread is :id:12
6 sum 15 and current thread is :id:15
6 sum 16 and current thread is :id:15
6 sum 18 and current thread is :id:15
6 sum 15 and current thread is :id:17
6 sum 19 and current thread is :id:17
6 sum 20 and current thread is :id:17
6 sum 21 and current thread is :id:17
6 sum 22 and current thread is :id:19
6 sum 23 and current thread is :id:19
6 sum 24 and current thread is :id:19
6 sum 25 and current thread is :id:19
6 sum 17 and current thread is :id:16
4 sum 26 and current thread is :id:16
4 sum 27 and current thread is :id:14
4 sum 28 and current thread is :id:16
4 sum 30 and current thread is :id:16
3 sum 31 and current thread is :id:18
3 sum 32 and current thread is :id:18
3 sum 33 and current thread is :id:18
3 sum 34 and current thread is :id:18
2 sum 35 and current thread is :id:20
4 sum 29 and current thread is :id:14
2 sum 37 and current thread is :id:14
2 sum 38 and current thread is :id:14
2 sum 36 and current thread is :id:20
1 sum 39 and current thread is :id:20
1 sum 40 and current thread is :id:20
40