public class Test11 {
volatile int count = 0;
void f(){
for(int i = 0 ; i < 10000 ; i ++ ){
count ++ ;
}
}
public static void main(String[] args) {
Test11 t = new Test11();
List<Thread> threads = new ArrayList<>();
for(int i = 0 ; i < 10 ; i ++ ){
threads.add(new Thread(t::f,"thread -"+i));
}
threads.forEach((o)->{o.start();});
threads.forEach((o)->{
try {
o.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println(t.count);
}
}
问:打印出来的值是十万吗?
不是。因为方法f不是原子性的,所以存在多个线程同时运行f方法,所以并不能保证加到十万。volatile只保证线程间的可见性,但不能保证原子性,而syncronized既保证了可见性,也保证了原子性
怎么做才正确呢?
1.将方法f用syncronized修饰。
2.改为如下代码:
AtomicInteger count = new AtomicInteger();
void f(){
for(int i = 0 ; i < 10000 ; i ++ ){
count.incrementAndGet() ;
}
}
AtomicInteger用了系统相当底层的实现,比syncronized的效率高得多得多,用来替代 count ++的。 count ++ 本身也不具备原子性,而AtomicInteger是具备原子性的。
思考题:
如果改为如下代码,请问会输出多少呢?这里还具备原子性吗?
AtomicInteger count = new AtomicInteger();
void f(){
for(int i = 0 ; i < 1000 ; i ++ ){
if(count.get()<1000) {
count.incrementAndGet();
}
}
}
作者:xhd老师不迟到
来源:CSDN
原文:https://blog.csdn.net/xhd731568849/article/details/89111149
版权声明:本文为博主原创文章,转载请附上博文链接!