Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Giới thiệu về API thu thập đồng thời trong Java

Các API bộ sưu tập đồng thời, ngoài API Bộ sưu tập Java, là một tập hợp các API bộ sưu tập được thiết kế và tối ưu hóa đặc biệt cho truy cập đa luồng được đồng bộ hóa. Chúng được nhóm trong java.util.concurrent bưu kiện. Bài viết này cung cấp một cái nhìn tổng quan và giới thiệu việc sử dụng nó bằng cách sử dụng một tình huống ví dụ thích hợp.

Tổng quan

Java đã hỗ trợ đa luồng và đồng thời ngay từ khi mới thành lập. Các chuỗi được tạo bằng cách triển khai Runnable giao diện hoặc mở rộng Chủ đề lớp. Đồng bộ hóa được thực hiện bằng từ khóa có tên là đồng bộ hóa . Java cũng cung cấp cơ chế giao tiếp giữa các luồng. Điều này đạt được với sự trợ giúp của thông báo () đợi () các phương thức, là một phần của Đối tượng lớp. Mặc dù các kỹ thuật đa luồng sáng tạo này là một phần của một số tính năng tuyệt vời của Java, nhưng chúng hơi thiếu hụt trong việc cung cấp nhu cầu của một lập trình viên đòi hỏi khả năng đa luồng chuyên sâu. Điều này là do một chương trình đồng thời cần nhiều thứ hơn là chỉ có thể tạo các luồng và thực hiện một số thao tác thô sơ. Nó yêu cầu nhiều tính năng cấp cao như nhóm luồng, trình quản lý thực thi, semaphores, v.v.

Khung thu thập hiện có

Java đã có một khung thu thập toàn diện. Các bộ sưu tập rất tốt về những gì chúng làm và cũng có thể được sử dụng trong các ứng dụng chuỗi Java. Ngoài ra, có một từ khóa, được gọi là đồng bộ hóa , để làm cho chúng an toàn. Mặc dù bề ngoài có vẻ như chúng rất hay được sử dụng trong đa luồng, nhưng cách thức đạt được độ an toàn của luồng là điểm nghẽn chính trong việc triển khai đồng thời nó. Ngoài việc đồng bộ hóa rõ ràng, chúng không được thiết kế theo mô hình triển khai đồng thời ngay từ đầu. Việc đồng bộ hóa các bộ sưu tập này được thực hiện bằng cách tuần tự hóa tất cả quyền truy cập vào trạng thái của bộ sưu tập. Điều này có nghĩa là, mặc dù chúng ta có thể có một số đồng thời, do quá trình xử lý tuần tự hóa cơ bản, nó hoạt động trên một nguyên tắc thực sự ngược lại. Việc tuần tự hóa gây ảnh hưởng nặng nề đến hiệu suất, đặc biệt khi nhiều luồng cạnh tranh để giành được khóa trên toàn bộ sưu tập.

API bộ sưu tập mới

API thu thập đồng thời là phần bổ sung cho Java từ phiên bản 5 và là một phần của gói có tên java.util.concurrent . Chúng là sự cải tiến của các API thu thập hiện có và đã được thiết kế để truy cập đồng thời từ nhiều luồng. Ví dụ: ConcurrentHashMap thực sự là lớp chúng ta cần khi muốn sử dụng Bản đồ dựa trên băm được đồng bộ hóa thực hiện. Tương tự, nếu chúng ta muốn có một Danh sách chi phối theo luồng, an toàn theo chuỗi , chúng tôi thực sự có thể sử dụng CopyOnWriterArrayList lớp. Bản đồ đồng thời mới giao diện cung cấp một số hành động kết hợp theo một phương pháp, chẳng hạn như putIfPresent , computeIfPresent , thay thế , hợp nhất , và như thế. Có nhiều lớp như vậy nằm trong khuôn khổ thu thập đồng thời mới. Để đặt tên cho một số: ArrayBlockingQueue , ConcurrentLinkedDeque , ConcurrentLinkedQueue , ConcurrentSkipListMap , ConcurrentSkipListSet , CopyOnWriteArraySet , DelayQueue , LinkedBlockingDeque , LinkedBlockingQueue , LinkedTransferQueue , PriorityBlockingQueue , SynchronousQueue và những người khác.

Hàng đợi

Các loại bộ sưu tập, chẳng hạn như Hàng đợi BlockingQueue , có thể được sử dụng để giữ một phần tử tạm thời, đang chờ truy xuất theo cách FIFO để xử lý. ConcurrentLinkQueue Mặt khác, là một hàng đợi FIFO truyền thống được triển khai như một hàng đợi không giới hạn, an toàn theo luồng dựa trên các nút được liên kết. PriorityBlockingQueue là hàng đợi chặn không bị ràng buộc sử dụng các chỉ tiêu sắp xếp giống như hàng đợi của Hàng đợi ưu tiên không đồng thời và các hoạt động truy xuất chặn nguồn cung cấp.

Bản đồ

Trong các lớp bộ sưu tập cũ hơn khi đồng bộ hóa được áp dụng, nó giữ các khóa trong suốt thời gian của mỗi hoạt động. Có các hoạt động, chẳng hạn như get phương pháp của HashMap hoặc chứa phương pháp của Danh sách , liên quan đến tính toán phức tạp đằng sau cảnh khi được gọi. Ví dụ:để tìm một phần tử cụ thể trong danh sách, nó sẽ tự động gọi bằng phương pháp. Phương pháp này yêu cầu tính toán nhất định để so sánh từng phần tử trong danh sách; có thể mất nhiều thời gian để hoàn thành nhiệm vụ. Điều này tồi tệ hơn trong một bộ sưu tập dựa trên băm. Nếu các phần tử trong bản đồ băm được phân bố không đồng đều, việc duyệt qua một danh sách dài và gọi các dấu bằng có thể mất rất nhiều thời gian. Đây là sự cố vì nó có thể ảnh hưởng đến hiệu suất tổng thể của ứng dụng.

Không giống như HashMap , ConcurrentHashMap sử dụng hoàn toàn một chiến lược khác. Thay vì cung cấp một khóa chung cho mọi phương pháp được đồng bộ hóa, nó sử dụng một kỹ thuật được gọi là khóa tước . Đây là một giải pháp tốt hơn cho cả tính đồng thời và khả năng mở rộng. Tước khóa sử dụng các ổ khóa riêng biệt cho các thùng riêng biệt. Kết quả là, sự cạnh tranh của luồng được tách ra khỏi cấu trúc dữ liệu bên dưới và thay vào đó được áp đặt vào nhóm. Ví dụ: việc triển khai ConcurrentHashMap sử dụng một mảng gồm 16 khóa — mỗi khóa bảo vệ 1/16 nhóm băm; thùng N được bảo vệ bởi khóa N mod 16… điều này làm giảm nhu cầu đối với bất kỳ khóa nhất định nào đi khoảng hệ số là 16. Đó là do kỹ thuật này mà ConcurrentHashMap hỗ trợ ít nhất 16 người viết đồng thời theo mặc định và hơn thế nữa có thể được đáp ứng theo yêu cầu.

CopyOnWriterArrayList

Đây là một giải pháp thay thế tốt cho Danh sách được đồng bộ hóa và không yêu cầu bạn áp dụng cơ chế khóa trong quá trình lặp lại. Các trình vòng lặp giữ lại một tham chiếu đến mảng hỗ trợ khi bắt đầu lặp và không thay đổi nó. Do đó, nó yêu cầu đồng bộ hóa ngắn gọn để lấy nội dung của mảng. Nhiều luồng có thể truy cập vào bộ sưu tập mà không can thiệp vào nhau. Ngay cả việc sửa đổi từ nhiều chủ đề cũng không bị tranh cãi. Có một bản đối chiếu đã đặt của danh sách mảng này, được gọi là CopyOnWriterSet , có thể được sử dụng để thay thế Set đã đồng bộ hóa về nhu cầu đồng thời.

Một ví dụ nhanh

Có nhiều lớp trong tập hợp đồng thời. Việc sử dụng chúng không quá khó đối với bất kỳ ai quen thuộc với bộ sưu tập cũ hơn. Vì mục đích đầy đủ, đây là một ví dụ để cung cấp cái nhìn sơ lược về cách sử dụng của nó trong lập trình Java.

package org.mano.example;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class ProducerConsumerDemo {
   static BlockingQueue<Integer> queue = new
      LinkedBlockingQueue<>(5);
   public static void main(String[] args) throws
         InterruptedException {
      int noOfProducers = 7;
      int noOfConsumers = 9;
      for (inti = 0; i < noOfProducers; i++) {
         new Thread(new Producer(), "PRODUCER").start();
      }
      for (int i = 0; i < noOfConsumers; i++) {
         new Thread(new Consumer(), "CONSUMER").start();
      }
      System.exit(0);
   }
   static class Producer implements Runnable {
      Random random = new Random();
      public void run() {
         try {
            int num = random.nextInt(100);
            queue.put(num);
            System.out.println("Produced: " + num
               + " Queue size : "+ queue.size());
            Thread.sleep(100);
         } catch (InterruptedException ex) {
            System.out.println("Producer is interrupted.");
         }
      }
   }
   static class Consumer implements Runnable {
      public void run() {
         try {
            System.out.println("Consumed: " + queue.take()
               + " Queue size : "+ queue.size());
            Thread.sleep(100);
         } catch (InterruptedException ex) {
            System.out.println("Consumer is interrupted.");
         }
      }
   }
}

Kết luận

Có lẽ lợi ích lớn nhất của việc sử dụng các lớp thu thập đồng thời là khả năng mở rộng và rủi ro thấp của chúng. Các API thu thập đồng thời của Java cung cấp một loạt các lớp được thiết kế đặc biệt để xử lý các hoạt động đồng thời. Các lớp này là các lựa chọn thay thế cho Khung Bộ sưu tập Java và cung cấp chức năng tương tự ngoại trừ sự hỗ trợ bổ sung của đồng thời. Do đó, đường cong học tập đối với lập trình viên đã biết về Java Collection Framework gần như không có. Các lớp được định nghĩa trong gói java.util.concurrent . Ở đây, tôi đã cố gắng đưa ra một cái nhìn tổng quan để bắt đầu và sử dụng các API thu thập bất cứ khi nào cần thiết.

Tài liệu tham khảo

  • Tài liệu Java API
  • Goetz, Brian và Tim Peierls. Java Concurrency trong thực tế . Pearson, 2013.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SCD loại 1

  2. Không gian bảng SYSMGMTDATA là ĐẦY ĐỦ trong Kho lưu trữ Quản lý Cơ sở Hạ tầng Lưới (MGMTDB)

  3. Đặt và xác định mục tiêu hàng trong kế hoạch thực thi

  4. Tải trọng gia tăng trong SSIS

  5. Giảm thiểu tác động của DBCC CHECKDB:DO và DONTs