有如下代码 private volatile int hc=0;
@Override
public int hashCode()
{
int result=hc;
if(result==0)
{
result=17;
result=result+something.hashCode();
.....
hc=result;
}
return result;
}这里的volitale有什么意义?
不是说读写 除long和double以外的基本类型 都是原子操作吗,那么也不存在hc=result时,写了一半被另一个线程读走的可能啊。
@Override
public int hashCode()
{
int result=hc;
if(result==0)
{
result=17;
result=result+something.hashCode();
.....
hc=result;
}
return result;
}这里的volitale有什么意义?
不是说读写 除long和double以外的基本类型 都是原子操作吗,那么也不存在hc=result时,写了一半被另一个线程读走的可能啊。
if(result==0)
{
result=17;
result=result+something.hashCode();
.....
hc=result;
}
这段代码里的result统一都用hc代替,那么在运算到 ..... 部分时,恰好另外一个线程来读取 hc 的值,那么hc的值就是一个垃圾值,没有任意意义的值
private volatile int hc = 0; // volatile的目的是且仅是保证hc=result是原子操作public int hashCode() {
if (hc == 0) {
synchronize (this) {
if (hc == 0) {
result = ...
...
hc = result; // 必须是原子操作
}
}
}
return hc;
}
private int hash; // Default to 0 public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count; for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
代码的作者知道hash = h的原子性,所以声明变量hash的时候没有加volatile关键字;而由于在这个问题里,几个线程多次计算hash的值也没有什么大不了的,所以根本没有加锁。
没什么大不了的啊。
求解答。
该好好读读的地方我都标记出来了,读不懂就问一个英文好点的或者读中文版,不能想当然
For the purposes of the Java programming language memory model, a single write to a non-volatile long or double value is treated as two separate writes: one to each 32-bit half. This can result in a situation where a thread sees the first 32 bits of a 64 bit value from one write, and the second 32 bits from another write. Writes and reads of volatile long and double values are always atomic. Writes to and reads of references are always atomic, regardless of whether they are implemented as 32 or 64 bit values.VM implementors are encouraged to avoid splitting their 64-bit values where possible. Programmers are encouraged to declare shared 64-bit values as volatile or synchronize their programs correctly to avoid possible complications.