Viscent/javamtia

老师你好我爱阅读第三章volatile锁的测试书中提供的counter类,不是太能理解

Opened this issue · 2 comments

问题描述:
1、测试结果中有两个线程拿到一样的值
2、还有一种情况是线程获取的值顺序不对
count的变量值在增加的时候使用了锁,也就是同时只有一个线程对count变量做修改,读取变量增量了volatile保障读取到最新的值,但是实际反复测试确不是这样,麻烦老师解惑下谢谢
测试的代码如下
package io.github.viscent.mtia.ch3.case03;

import io.github.viscent.mtia.ch3.Counter;
import io.github.viscent.mtia.util.Debug;

public class ThreadTest {
public static void main(String[] args) {
Counter counter = new Counter();

    Thread thread =new Thread(){
        @Override
        public void run() {
            for(int i=0;i<50;i++){
                counter.increment();
                Debug.info(counter.vaule()+"");
            }
        }
    };

    Thread thread1 =new Thread(){
        @Override
        public void run() {
            for(int i=0;i<50;i++){
                counter.increment();
                Debug.info(counter.vaule()+"");
            }
        }
    };
    thread.start();
    thread1.start();
}

}
问题1 的测试结果
[2020-07-08 10:16:44.446][INFO][Thread-0]:2
[2020-07-08 10:16:44.446][INFO][Thread-1]:2
[2020-07-08 10:16:44.451][INFO][Thread-0]:3
[2020-07-08 10:16:44.451][INFO][Thread-1]:4
[2020-07-08 10:16:44.451][INFO][Thread-0]:5
[2020-07-08 10:16:44.451][INFO][Thread-1]:6
[2020-07-08 10:16:44.451][INFO][Thread-0]:7
[2020-07-08 10:16:44.451][INFO][Thread-1]:8
[2020-07-08 10:16:44.451][INFO][Thread-0]:9
[2020-07-08 10:16:44.451][INFO][Thread-1]:10
[2020-07-08 10:16:44.451][INFO][Thread-0]:11
[2020-07-08 10:16:44.451][INFO][Thread-1]:12
[2020-07-08 10:16:44.452][INFO][Thread-0]:13
[2020-07-08 10:16:44.452][INFO][Thread-0]:15
[2020-07-08 10:16:44.452][INFO][Thread-1]:14
[2020-07-08 10:16:44.452][INFO][Thread-0]:16
[2020-07-08 10:16:44.452][INFO][Thread-0]:17
[2020-07-08 10:16:44.452][INFO][Thread-0]:18
[2020-07-08 10:16:44.452][INFO][Thread-0]:19
[2020-07-08 10:16:44.452][INFO][Thread-1]:20
[2020-07-08 10:16:44.452][INFO][Thread-0]:21
[2020-07-08 10:16:44.452][INFO][Thread-1]:22
[2020-07-08 10:16:44.452][INFO][Thread-0]:23
[2020-07-08 10:16:44.453][INFO][Thread-1]:24
[2020-07-08 10:16:44.453][INFO][Thread-0]:25
[2020-07-08 10:16:44.453][INFO][Thread-1]:26
[2020-07-08 10:16:44.453][INFO][Thread-0]:27
[2020-07-08 10:16:44.453][INFO][Thread-1]:28
[2020-07-08 10:16:44.453][INFO][Thread-1]:30
[2020-07-08 10:16:44.453][INFO][Thread-0]:29
[2020-07-08 10:16:44.453][INFO][Thread-1]:31
[2020-07-08 10:16:44.453][INFO][Thread-0]:32
[2020-07-08 10:16:44.453][INFO][Thread-1]:33
[2020-07-08 10:16:44.454][INFO][Thread-0]:34
[2020-07-08 10:16:44.454][INFO][Thread-1]:35
[2020-07-08 10:16:44.454][INFO][Thread-0]:36
[2020-07-08 10:16:44.454][INFO][Thread-1]:37
[2020-07-08 10:16:44.454][INFO][Thread-0]:38
[2020-07-08 10:16:44.454][INFO][Thread-1]:39
[2020-07-08 10:16:44.454][INFO][Thread-0]:40
[2020-07-08 10:16:44.454][INFO][Thread-1]:41
[2020-07-08 10:16:44.454][INFO][Thread-0]:42
[2020-07-08 10:16:44.454][INFO][Thread-1]:43
[2020-07-08 10:16:44.454][INFO][Thread-0]:44
[2020-07-08 10:16:44.454][INFO][Thread-1]:45
[2020-07-08 10:16:44.454][INFO][Thread-0]:46
[2020-07-08 10:16:44.454][INFO][Thread-1]:47
[2020-07-08 10:16:44.455][INFO][Thread-0]:48
[2020-07-08 10:16:44.455][INFO][Thread-1]:49
[2020-07-08 10:16:44.455][INFO][Thread-0]:50
[2020-07-08 10:16:44.455][INFO][Thread-1]:51
[2020-07-08 10:16:44.455][INFO][Thread-0]:52
[2020-07-08 10:16:44.455][INFO][Thread-1]:53
[2020-07-08 10:16:44.455][INFO][Thread-0]:54
[2020-07-08 10:16:44.455][INFO][Thread-1]:55
[2020-07-08 10:16:44.455][INFO][Thread-0]:56
[2020-07-08 10:16:44.455][INFO][Thread-1]:57
[2020-07-08 10:16:44.455][INFO][Thread-0]:58
[2020-07-08 10:16:44.455][INFO][Thread-1]:59
[2020-07-08 10:16:44.455][INFO][Thread-0]:60
[2020-07-08 10:16:44.456][INFO][Thread-1]:61
[2020-07-08 10:16:44.456][INFO][Thread-0]:62
[2020-07-08 10:16:44.456][INFO][Thread-1]:63
[2020-07-08 10:16:44.456][INFO][Thread-0]:64
[2020-07-08 10:16:44.456][INFO][Thread-1]:65
[2020-07-08 10:16:44.456][INFO][Thread-0]:66
[2020-07-08 10:16:44.456][INFO][Thread-1]:67
[2020-07-08 10:16:44.456][INFO][Thread-0]:68
[2020-07-08 10:16:44.456][INFO][Thread-1]:69
[2020-07-08 10:16:44.456][INFO][Thread-0]:70
[2020-07-08 10:16:44.456][INFO][Thread-1]:71
[2020-07-08 10:16:44.456][INFO][Thread-0]:72
[2020-07-08 10:16:44.456][INFO][Thread-1]:73
[2020-07-08 10:16:44.457][INFO][Thread-0]:74
[2020-07-08 10:16:44.457][INFO][Thread-1]:75
[2020-07-08 10:16:44.457][INFO][Thread-0]:76
[2020-07-08 10:16:44.457][INFO][Thread-1]:77
[2020-07-08 10:16:44.457][INFO][Thread-0]:78
[2020-07-08 10:16:44.457][INFO][Thread-1]:79
[2020-07-08 10:16:44.457][INFO][Thread-0]:80
[2020-07-08 10:16:44.457][INFO][Thread-1]:81
[2020-07-08 10:16:44.457][INFO][Thread-0]:82
[2020-07-08 10:16:44.457][INFO][Thread-1]:83
[2020-07-08 10:16:44.457][INFO][Thread-0]:84
[2020-07-08 10:16:44.458][INFO][Thread-1]:85
[2020-07-08 10:16:44.458][INFO][Thread-0]:86
[2020-07-08 10:16:44.458][INFO][Thread-1]:87
[2020-07-08 10:16:44.458][INFO][Thread-0]:88
[2020-07-08 10:16:44.458][INFO][Thread-1]:89
[2020-07-08 10:16:44.458][INFO][Thread-0]:90
[2020-07-08 10:16:44.458][INFO][Thread-1]:91
[2020-07-08 10:16:44.458][INFO][Thread-0]:92
[2020-07-08 10:16:44.458][INFO][Thread-1]:93
[2020-07-08 10:16:44.458][INFO][Thread-0]:94
[2020-07-08 10:16:44.458][INFO][Thread-1]:95
[2020-07-08 10:16:44.458][INFO][Thread-0]:96
[2020-07-08 10:16:44.458][INFO][Thread-1]:97
[2020-07-08 10:16:44.459][INFO][Thread-1]:98
[2020-07-08 10:16:44.459][INFO][Thread-1]:99
[2020-07-08 10:16:44.459][INFO][Thread-1]:100
问题2的测试结果
[2020-07-08 10:36:42.029][INFO][Thread-1]:2
[2020-07-08 10:36:42.029][INFO][Thread-0]:1
[2020-07-08 10:36:42.033][INFO][Thread-1]:3
[2020-07-08 10:36:42.033][INFO][Thread-0]:4
[2020-07-08 10:36:42.033][INFO][Thread-1]:5
[2020-07-08 10:36:42.034][INFO][Thread-1]:7
[2020-07-08 10:36:42.034][INFO][Thread-1]:8
[2020-07-08 10:36:42.035][INFO][Thread-1]:9
[2020-07-08 10:36:42.035][INFO][Thread-1]:10
[2020-07-08 10:36:42.034][INFO][Thread-0]:6
[2020-07-08 10:36:42.035][INFO][Thread-1]:11
[2020-07-08 10:36:42.035][INFO][Thread-1]:13
[2020-07-08 10:36:42.035][INFO][Thread-0]:12
[2020-07-08 10:36:42.035][INFO][Thread-0]:15
[2020-07-08 10:36:42.035][INFO][Thread-0]:16
[2020-07-08 10:36:42.035][INFO][Thread-1]:14
[2020-07-08 10:36:42.035][INFO][Thread-0]:17
[2020-07-08 10:36:42.035][INFO][Thread-1]:18
[2020-07-08 10:36:42.035][INFO][Thread-0]:19
[2020-07-08 10:36:42.035][INFO][Thread-0]:21
[2020-07-08 10:36:42.035][INFO][Thread-0]:22
[2020-07-08 10:36:42.035][INFO][Thread-1]:20
[2020-07-08 10:36:42.035][INFO][Thread-0]:23
[2020-07-08 10:36:42.036][INFO][Thread-0]:25
[2020-07-08 10:36:42.036][INFO][Thread-1]:24
[2020-07-08 10:36:42.036][INFO][Thread-0]:26
[2020-07-08 10:36:42.036][INFO][Thread-1]:27
[2020-07-08 10:36:42.036][INFO][Thread-0]:28
[2020-07-08 10:36:42.036][INFO][Thread-1]:29
[2020-07-08 10:36:42.036][INFO][Thread-0]:30
[2020-07-08 10:36:42.036][INFO][Thread-1]:31
[2020-07-08 10:36:42.036][INFO][Thread-0]:32
[2020-07-08 10:36:42.036][INFO][Thread-1]:33
[2020-07-08 10:36:42.037][INFO][Thread-0]:34
[2020-07-08 10:36:42.037][INFO][Thread-1]:35
[2020-07-08 10:36:42.037][INFO][Thread-0]:36
[2020-07-08 10:36:42.037][INFO][Thread-1]:37
[2020-07-08 10:36:42.037][INFO][Thread-0]:38
[2020-07-08 10:36:42.037][INFO][Thread-1]:39
[2020-07-08 10:36:42.037][INFO][Thread-0]:40
[2020-07-08 10:36:42.037][INFO][Thread-1]:41
[2020-07-08 10:36:42.037][INFO][Thread-0]:42
[2020-07-08 10:36:42.037][INFO][Thread-1]:43
[2020-07-08 10:36:42.037][INFO][Thread-0]:44
[2020-07-08 10:36:42.038][INFO][Thread-1]:45
[2020-07-08 10:36:42.038][INFO][Thread-0]:46
[2020-07-08 10:36:42.038][INFO][Thread-1]:47
[2020-07-08 10:36:42.038][INFO][Thread-0]:48
[2020-07-08 10:36:42.038][INFO][Thread-1]:49
[2020-07-08 10:36:42.038][INFO][Thread-0]:50
[2020-07-08 10:36:42.038][INFO][Thread-1]:51
[2020-07-08 10:36:42.038][INFO][Thread-1]:53
[2020-07-08 10:36:42.038][INFO][Thread-0]:52
[2020-07-08 10:36:42.038][INFO][Thread-1]:54
[2020-07-08 10:36:42.038][INFO][Thread-0]:55
[2020-07-08 10:36:42.038][INFO][Thread-1]:56
[2020-07-08 10:36:42.038][INFO][Thread-0]:57
[2020-07-08 10:36:42.039][INFO][Thread-1]:58
[2020-07-08 10:36:42.039][INFO][Thread-0]:59
[2020-07-08 10:36:42.039][INFO][Thread-1]:60
[2020-07-08 10:36:42.039][INFO][Thread-0]:61
[2020-07-08 10:36:42.039][INFO][Thread-1]:62
[2020-07-08 10:36:42.039][INFO][Thread-0]:63
[2020-07-08 10:36:42.039][INFO][Thread-0]:65
[2020-07-08 10:36:42.040][INFO][Thread-0]:66
[2020-07-08 10:36:42.040][INFO][Thread-0]:67
[2020-07-08 10:36:42.040][INFO][Thread-0]:68
[2020-07-08 10:36:42.040][INFO][Thread-0]:69
[2020-07-08 10:36:42.040][INFO][Thread-0]:70
[2020-07-08 10:36:42.040][INFO][Thread-0]:71
[2020-07-08 10:36:42.040][INFO][Thread-0]:72
[2020-07-08 10:36:42.041][INFO][Thread-0]:73
[2020-07-08 10:36:42.041][INFO][Thread-0]:74
[2020-07-08 10:36:42.041][INFO][Thread-0]:75
[2020-07-08 10:36:42.039][INFO][Thread-1]:64
[2020-07-08 10:36:42.041][INFO][Thread-1]:77
[2020-07-08 10:36:42.042][INFO][Thread-1]:78
[2020-07-08 10:36:42.042][INFO][Thread-1]:79
[2020-07-08 10:36:42.042][INFO][Thread-1]:80
[2020-07-08 10:36:42.041][INFO][Thread-0]:76
[2020-07-08 10:36:42.042][INFO][Thread-1]:81
[2020-07-08 10:36:42.042][INFO][Thread-0]:82
[2020-07-08 10:36:42.042][INFO][Thread-1]:83
[2020-07-08 10:36:42.042][INFO][Thread-0]:84
[2020-07-08 10:36:42.042][INFO][Thread-1]:85
[2020-07-08 10:36:42.043][INFO][Thread-1]:87
[2020-07-08 10:36:42.043][INFO][Thread-1]:88
[2020-07-08 10:36:42.043][INFO][Thread-1]:89
[2020-07-08 10:36:42.042][INFO][Thread-0]:86
[2020-07-08 10:36:42.043][INFO][Thread-1]:90
[2020-07-08 10:36:42.043][INFO][Thread-0]:91
[2020-07-08 10:36:42.043][INFO][Thread-1]:92
[2020-07-08 10:36:42.043][INFO][Thread-0]:93
[2020-07-08 10:36:42.043][INFO][Thread-1]:94
[2020-07-08 10:36:42.043][INFO][Thread-0]:95
[2020-07-08 10:36:42.043][INFO][Thread-1]:96
[2020-07-08 10:36:42.044][INFO][Thread-1]:98
[2020-07-08 10:36:42.044][INFO][Thread-1]:99
[2020-07-08 10:36:42.044][INFO][Thread-1]:100
[2020-07-08 10:36:42.044][INFO][Thread-0]:97

刚看到这里,碰巧看到了这个问题,说下我的理解(不保证正确),希望能对你有所帮助 :-)

其实每个线程增加50次,输出值中有100,说明counter的增加是符合预期的

1、测试结果中有两个线程拿到一样的值
两个线程并发读取volatile变量count的值,当然可能是一样的

2、还有一种情况是线程获取的值顺序不对

// 增加counter与打印counter并不是一个原子操作
counter.increment();
Debug.info(counter.vaule()+"");
thread1 thread2
counter.increment(); //counter = x
str = counter.vaule()+"" // "x"
counter.increment(); //counter = x + 1
str = counter.vaule()+"" // "x + 1"
Debug.info(str) // "x+1";
Debug.info(str) // "x";

3、count的变量值在增加的时候使用了锁
是CAS,不是锁

4、同时只有一个线程对count变量做修改,读取变量增量了volatile保障读取到最新的值
volatile不保证能读到最新值 ,书上有几次提到。 @markIsCat

刚看到这里,碰巧看到了这个问题,说下我的理解(不保证正确),希望能对你有所帮助 :-)

其实每个线程增加50次,输出值中有100,说明counter的增加是符合预期的

1、测试结果中有两个线程拿到一样的值
两个线程并发读取volatile变量count的值,当然可能是一样的

2、还有一种情况是线程获取的值顺序不对

// 增加counter与打印counter并不是一个原子操作
counter.increment();
Debug.info(counter.vaule()+"");

thread1 thread2
counter.increment(); //counter = x
str = counter.vaule()+"" // "x"
counter.increment(); //counter = x + 1
str = counter.vaule()+"" // "x + 1"
Debug.info(str) // "x+1";
Debug.info(str) // "x";
3、count的变量值在增加的时候使用了锁
是CAS,不是锁

4、同时只有一个线程对count变量做修改,读取变量增量了volatile保障读取到最新的值
volatile不保证能读到最新值 ,书上有几次提到。 @markIsCat

仔细看完你的解释差不多明白了,感谢!