2012-02-26 33 views
6

Tôi đang cố gắng lặp qua một trình lặp Java đồng thời, nhưng đang gặp khó khăn với cách tốt nhất để làm điều này.Java Iterator Concurrency

Đây là những gì tôi có ở đó tôi không cố gắng làm bất cứ điều gì đồng thời.

Long l;  
Iterator<Long> i = getUserIDs(); 

while (i.hasNext()) { 
    l = i.next(); 

    someObject.doSomething(l); 
    anotheObject.doSomething(l); 
} 

Không có điều kiện chủng tộc giữa những thứ tôi đang làm trên các đối tượng không lặp lại, vì vậy tôi không quá lo lắng về điều đó. Tôi chỉ muốn tăng tốc độ mất bao lâu để lặp qua trình lặp bằng cách không thực hiện tuần tự.

Xin cảm ơn trước.

Trả lời

4

Một giải pháp là sử dụng một người thi hành để song song công việc của bạn.

đơn giản ví dụ:

ExecutorService executor = Executors.newCachedThreadPool(); 

Iterator<Long> i = getUserIDs(); 
while (i.hasNext()) { 
    final Long l = i.next(); 

    Runnable task = new Runnable() { 
     public void run() { 
      someObject.doSomething(l); 
      anotheObject.doSomething(l); 
     } 
    } 

    executor.submit(task); 
} 

executor.shutdown(); 

này sẽ tạo ra một chủ đề mới cho mỗi mục trong iterator, sau đó sẽ làm việc. Bạn có thể điều chỉnh số lượng chuỗi được sử dụng bằng cách sử dụng phương thức khác trên lớp Executors hoặc chia nhỏ công việc như bạn thấy phù hợp (ví dụ: Runnable khác nhau cho mỗi cuộc gọi phương thức).

5

A có thể cung cấp hai cách tiếp cận có thể:

  • Sử dụng một hồ bơi thread và cử các mặt hàng nhận được từ iterator để một tập hợp các luồng xử lý. Điều này sẽ không đẩy nhanh bản thân các hoạt động của trình vòng lặp, vì những điều đó vẫn sẽ xảy ra trong một luồng đơn, nhưng nó sẽ song song với việc xử lý thực tế.

  • Tùy thuộc vào cách lặp được tạo, bạn có thể có thể chia quá trình lặp đi lặp lại để nhiều đoạn, mỗi để được xử lý bởi một thread riêng biệt thông qua một đối tượng khác nhau Iterator. Ví dụ, hãy xem các phương pháp List.sublist(int fromIndex, int toIndex)List.listIterator(int index).

    Điều này sẽ cho phép các thao tác lặp xảy ra song song, nhưng không phải lúc nào cũng có thể phân đoạn lặp lại như thế này, thường là do thực tế đơn giản là các mục được lặp lại không có sẵn ngay lập tức. Là một thủ thuật tiền thưởng, nếu các hoạt động lặp lại đắt hoặc chậm, chẳng hạn như những thao tác cần thiết để truy cập cơ sở dữ liệu, bạn có thể thấy cải thiện thông lượng nếu bạn tách chúng ra thành một chuỗi riêng biệt. trong một số BlockingQueue. Chuỗi điều phối sau đó sẽ chỉ phải truy cập vào hàng đợi mà không phải đợi đối tượng iterator để truy xuất mục tiếp theo.

Lời khuyên quan trọng nhất trong trường hợp này là: "Sử dụng hồ sơ của bạn", thường là để được theo sau bởi "Không tối ưu hóa sớm". Bằng cách sử dụng profiler, chẳng hạn như VisualVM, bạn sẽ có thể xác định nguyên nhân chính xác của về bất kỳ vấn đề hiệu suất nào, mà không chụp ảnh trong bóng tối.

1

Nếu bạn đang sử dụng Java 7, bạn có thể sử dụng fork/join mới; xem tutorial.

Nó không chỉ tự động chia các tác vụ giữa các chuỗi, mà nếu một số chủ đề hoàn thành nhiệm vụ của nó sớm hơn các chủ đề khác, nó "đánh cắp" một số tác vụ từ các chủ đề khác.