2016-07-13 16 views
8

Nếu trình vòng lặp không an toàn tạo ra một bản sao riêng và làm việc trên đó, làm cách nào nó nhận thức được bất kỳ thay đổi nào được thực hiện đối với bản gốc?Logic của trình lặp không an toàn là gì?

public class concurrentHashMap { 
    public static void main(String[] args) throws InterruptedException { 
     MapCheck obj1 = new MapCheck(); 
     Thread t1 = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       obj1.put(); 
      } 
     }); 

     Thread t2 = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       obj1.iterte(); 
      } 
     }); 

     t1.start(); 
     t2.start(); 
     t1.join(); 
     t2.join(); 
    } 
} 

class MapCheck { 
    Map<Integer,String> map = new ConcurrentHashMap<>(); 
    { 
     map.put(1, "pujan"); 
     map.put(2, "manish"); 
     map.put(3, "swati"); 
    } 

    void iterte() throws InterruptedException { 
     for (int key : map.keySet()) { 
      Thread.sleep(2000); 
      System.out.println(map.get(key)); 
     } 
    } 

    void put() throws InterruptedException{ 
     Thread.sleep(2000); 
     map.put(1, "pujan1"); 
     map.put(2, "manish1"); 
     map.put(3, "swati1"); 
    } 
} 

Đầu ra là:

pujan1 
manish1 
swati1 

Trả lời

12

Không có những điều như một iterator "không an toàn" trong Java. Ít nhất, các đặc tả Java SE không định nghĩa một thuật ngữ như vậy. Do đó, tôi khuyên bạn nên tránh sử dụng thuật ngữ "không an toàn" để mô tả các trình lặp Java.

Tôi biết rằng nhiều bài viết trên Internet và các nơi khác trên Stack Overflow sử dụng cụm từ "không an toàn", nhưng cách sử dụng của chúng không xác định và có thể không chính xác hoặc ít gây hiểu lầm nhất. Tôi tin rằng bạn đã bị lừa bởi tài liệu đó.

Có vẻ như bạn đã đọc ở đâu đó rằng trình lặp lặp "không an toàn" hoạt động trên một bản sao riêng biệt. Trong ví dụ của bạn, bạn sử dụng ConcurrentHashMap, thực sự có các trình lặp không nhanh. Tuy nhiên, các trình vòng lặp của CHM không hoạt động trên một bản sao. Thay vào đó, họ có ngữ nghĩa được mô tả bởi các đặc điểm kỹ thuật chính thức như weakly consistent. Định nghĩa là hơi trừu tượng, nhưng về cơ bản, bất kỳ phần tử nào được báo cáo bởi một trình lặp như vậy được đảm bảo đã tồn tại trong bộ sưu tập tại một thời điểm nào đó. Các loại trình vòng lặp này có thể hoặc không thể phản ánh các thay đổi đối với bộ sưu tập đã được thực hiện sau khi bắt đầu lặp lại. Đó là lý do tại sao luồng đang chạy trình vòng lặp thấy các thay đổi được thực hiện bởi luồng khác. (Cũng có thể một số hoặc không có thay đổi nào hiển thị, vì các chủ đề này có một cuộc đua dữ liệu.)

Ví dụ về bộ sưu tập khác có vòng lặp không nhanh là CopyOnWriteArrayList. Bộ lặp của bộ sưu tập này hoạt động trên ảnh chụp nhanh, do đó mọi thay đổi tiếp theo đối với bộ sưu tập là không bao giờ được hiển thị thông qua một trình lặp vòng.

Để hoàn tất, dưới đây là định nghĩa của trình biến đổi fail-fast từ đặc điểm kỹ thuật ArrayList. Hầu hết các bộ sưu tập khác (không đồng thời) trong Java có một chính sách lặp lại không nhanh được xác định tương tự.

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