1、CopyOnWriteArrayList 这个类我知道是在写的时候复制一个新的类,在新的类上进行修改,那这个时候读的不就可能会不准确了?(读的是老数据呀)
2、java.util.Collections#synchronizedCollection(java.util.Collection<T>) 这个方法返回的List,里面的所有方法都加了锁,为啥get方法也要加锁,是为了保持读和写的数据一致?那CopyOnWriteArrayList不就保证不了读写的时候数据的一致了吗?
1、CopyOnWriteArrayList 这个类我知道是在写的时候复制一个新的类,在新的类上进行修改,那这个时候读的不就可能会不准确了?(读的是老数据呀)
2、java.util.Collections#synchronizedCollection(java.util.Collection<T>) 这个方法返回的List,里面的所有方法都加了锁,为啥get方法也要加锁,是为了保持读和写的数据一致?那CopyOnWriteArrayList不就保证不了读写的时候数据的一致了吗?
Let me show you by example what is a legal way for a JIT to compile your code. You write:
while (myBean.getValue() > 1.0) {
// perform some action
Thread.sleep(1);
}
JIT compiles:
if (myBean.getValue() > 1.0)
while (true) {
// perform some action
Thread.sleep(1);
}
In just slightly different scenarios even the Java compiler could prouduce similar bytecode (it would only have to eliminate the possibility of dynamic dispatch to a different getValue). This is a textbook example of hoisting.
Why is this legal? The compiler has the right to assume that the result of myBean.getValue() can never change while executing above code. Without synchronized it is allowed to ignore any actions by other threads.
8 回答6.4k 阅读
1 回答4.1k 阅读✓ 已解决
3 回答2.3k 阅读✓ 已解决
2 回答3.2k 阅读
2 回答3.9k 阅读
1 回答2.2k 阅读✓ 已解决
3 回答1.6k 阅读✓ 已解决
对,你理解的是对的,确实可能发生脏读。
所以
CopyOnWriteArrayList
只能保证数据的最终一致性,不能保证数据的实时一致性,适合读多写少、脏数据对业务没啥影响的并发情况(比如令牌桶)。要想完全不脏读,那还是
synchronizedCollection
,但这个容器比较耗费性能。选择哪个容器,需要具体业务具体分析。