HLhakey
HLhakey
2017-08-16 07:38
采纳率: 100%
浏览 2.5k
已采纳

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

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());

        }
    }
}

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

6条回答 默认 最新

  • qq_33727653
    砸死接触 2017-08-16 13:22
    已采纳

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

    点赞 评论
  • HLhakey
    HLhakey 2017-08-16 07:38
     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());
    
            }
        }
    }
    
    
    点赞 评论
  • HLhakey
    HLhakey 2017-08-16 07:40

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

     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
    
    
    点赞 评论
  • zy841958835
    cloudyzhao 2017-08-16 07:43

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

    点赞 评论
  • u012988099
    karashiacid 2017-08-16 09:46

    因为并没有给线程加锁来进行同步
    所以在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

    点赞 评论
  • HLhakey
    HLhakey 2017-08-17 09:16

    去掉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

    点赞 评论

相关推荐