2017-04-27 15 views
10

Nhìn vào lớp String của Java, chúng ta có thể thấy mã băm được lưu trữ sau lần đánh giá đầu tiên.java String hashcode cơ chế lưu bộ nhớ đệm

public int hashCode() { 
    int h = hash; 
    if (h == 0 && value.length > 0) { 
     char val[] = value; 

     for (int i = 0; i < value.length; i++) { 
      h = 31 * h + val[i]; 
     } 
     hash = h; 
    } 
    return h; 
} 

Trường hợp hash là một biến mẫu. Tôi có một câu hỏi, tại sao chúng ta cần h biến phụ?

+1

Nó được viết như thế này để đảm bảo rằng lớp 'String' là an toàn luồng. Bạn có thể đọc thêm về khái niệm này [ở đây] (https://en.wikipedia.org/wiki/Thread_safety) – Valy

+1

Liên kết Wikipedia đó không giải thích đầy đủ những gì đang diễn ra ở đây hoặc tại sao. –

Trả lời

5

Đơn giản chỉ vì hash thay đổi giá trị trong vòng lặp và giải pháp của bạn mà không có biến tạm thời trung gian không an toàn chỉ. Hãy xem xét rằng phương thức này được gọi trong một số luồng.

Nói thread-1 bắt đầu hash tính toán và không còn là 0 nữa. Một thời điểm nhỏ sau đó thread-2 gọi cùng một phương thức hashCode() trên cùng một đối tượng và thấy rằng hash không phải là 0, nhưng thread-1 chưa hoàn thành tính toán của nó. Kết quả là, trong giá trị thread-2 sai hash (không được tính đầy đủ) sẽ được sử dụng.

3

Đó là cơ chế đồng bộ hóa đơn giản và rẻ tiền.

Nếu một chuỗi gọi hàm hashCode() lần đầu tiên và chuỗi thứ hai gọi lại trong khi chuỗi đầu tiên tính toán băm, chuỗi thứ hai sẽ trả về giá trị băm không chính xác (giá trị trung gian của phép tính trong chuỗi đầu tiên) nếu sử dụng trực tiếp thuộc tính.

+1

Lưu ý rằng độ an toàn của luồng tại đây không ngăn không cho tính băm từ nhiều hơn một chuỗi. Vì không có cơ chế đồng bộ hóa, nên không có sự đảm bảo rằng a) hai luồng sẽ không truy cập 'băm' trong khi nó vẫn là' 0', và b) mà ngay cả sau khi một luồng làm bộ nhớ đệm mà bất kỳ chuỗi nào khác sẽ thấy kết quả. Tại sao nó thread an toàn mặc dù có thể được tính toán nhiều lần? Bởi vì tính toán là không đáng kể; không có hai chủ đề nào có thể tính toán các giá trị khác nhau. –

+2

Hoàn toàn đúng, Lew. Trong trường hợp đó, tính toán gấp đôi băm có tác động nhỏ ngay từ đầu so với lợi ích của việc không cần bất kỳ cơ chế đồng bộ nào trong suốt vòng đời của chuỗi. – Mario

1

Để đặt nó rất đơn giản: nguyên thủy địa phương h cũng là địa phương; do đó an toàn ren; trái ngược với hash được chia sẻ.

Các vấn đề liên quan