Database
 sql >> база данни >  >> RDS >> Database

Въведение в API за едновременно събиране в Java

Едновременните API за колекция, освен Java Collection API, са набор от API за колекции, които са проектирани и оптимизирани специално за синхронизиран многонишков достъп. Те са групирани под java.util.concurrent пакет. Тази статия предоставя общ преглед и представя нейното използване с помощта на подходящ примерен сценарий.

Общ преглед

Java поддържа многонишковост и паралелност от самото си създаване. Нишките се създават или чрез внедряване на Runnable интерфейс или разширяване на Нишката клас. Синхронизацията се постига с ключовата дума, наречена синхронизация . Java също така предоставя механизма за комуникация между нишките. Това се постига с помощта на notify() и изчакайте() методи, които са част от обекта клас. Въпреки че тези иновативни многонишкови техники са част от някои от отличните характеристики на Java, те донякъде не успяват да осигурят нуждата от програмист, който изисква интензивна многонишкова способност от кутията. Това е така, защото едновременната програма се нуждае от нещо повече от това да може да създава нишки и да извършва някои елементарни манипулации. Изисква много функции на високо ниво, като пулове на нишки, мениджъри на изпълнение, семафори и така нататък.

Съществуваща рамка за колекция

Java вече има цялостна рамка за колекция. Колекциите са много добри в това, което правят и могат да се използват и в приложения за нишки на Java. Освен това има ключова дума, наречена синхронизиран , за да ги направи безопасни за конци. Въпреки че на пръв поглед може да изглежда, че са хубави да се използват в многонишковост, начинът, по който се постига безопасността на нишките, е основното препятствие в едновременното им изпълнение. Освен изричното синхронизиране, те не са проектирани под парадигмата на едновременното изпълнение от самото начало. Синхронизирането на тези колекции се постига чрез сериализиране на целия достъп до състоянието на колекцията. Това означава, че въпреки че може да имаме известен паралелизъм, поради основната сериализирана обработка, той работи на принцип, който всъщност е обратен. Сериализацията се отразява сериозно върху производителността, особено когато множество нишки се конкурират за заключването в цялата колекция.

Нови API за колекция

API за едновременно събиране са допълнение към Java от версия 5 и са част от пакета, наречен java.util.concurrent . Те са подобрение на съществуващите API за колекция и са проектирани за едновременен достъп от множество нишки. Например ConcurrentHashMap всъщност е класът, от който се нуждаем, когато искаме да използваме синхронизирана карта, базирана на хеш изпълнение. По същия начин, ако искаме доминиращ при преминаване, безопасен за нишки списък , всъщност можем да използваме CopyOnWriterArrayList клас. Новата ConcurrentMap интерфейсът предоставя редица съставни действия под един метод, като например putIfPresent , computeIfPresent , заменете , сливане , и така нататък. Има много такива класове, които са в рамките на новата рамка за едновременно събиране. За да назовем няколко:ArrayBlockingQueue , ConcurrentLinkedDeque , ConcurrentLinkedQueue , ConcurrentSkipListMap , ConcurrentSkipListSet , CopyOnWriteArraySet , DelayQueue , LinkedBlockingDeque , LinkedBlockingQueue , LinkedTransferQueue , PriorityBlockingQueue , SynchronousQueue , и други.

Опашки

Типовете колекции, като Опашка и BlockingQueue , може да се използва за временно задържане на елемент, изчаква се извличане по FIFO начин за обработка. ConcurrentLinkQueue , от друга страна, е традиционна FIFO опашка, реализирана като неограничена, нишобезопасна опашка, базирана на свързани възли. PriorityBlockingQueue е неограничена блокираща опашка, която използва същите норми за подреждане като тази на неконкурентната PriorityQueue и консумативи, блокиращи операции по извличане.

Карти

В по-старите колекционни класове, когато се прилага синхронизация, тя държи заключвания за продължителността на всяка операция. Има операции, като get метод на HashMap или съдържа метод на Списък , които включват сложни изчисления зад сцената, когато са извикани. Например, за да намери конкретен елемент в списък, той автоматично извиква equals метод. Този метод изисква определени изчисления за сравняване на всеки елемент от списъка; може да отнеме много време за изпълнение на задачата. Това е по-лошо в колекция, базирана на хеш. Ако елементите в хеш-картите са неравномерно разпределени, преминаването на дълъг списък и извикването на equals може да отнеме много време. Това е проблем, защото може да повлияе на цялостната производителност на приложението.

За разлика от HashMap , ConcurrentHashMap използва съвсем различна стратегия. Вместо да предоставя обща ключалка за всеки синхронизиран метод, той използва техника, наречена изчистване на заключване . Това е по-добро решение както за едновременност, така и за мащабируемост. Отстраняването на ключалката използва отделни ключалки за отделни кофи. В резултат на това спорът с нишките се отделя от основната структура от данни и вместо това се налага върху кофата. Например, имплементацията на ConcurrentHashMap използва масив от 16 ключалки – всяка от които пази 1/16 от хеш кофите; кофата N е защитена от ключалка N мод 16... това намалява търсенето на всяка дадена ключалка с приблизително коефициент 16. Благодарение на тази техника ConcurrentHashMap поддържа поне 16 едновременни записващи по подразбиране и повече могат да бъдат настанени при поискване.

CopyOnWriterArrayList

Това е добра алтернатива на синхронизирания списък и не изисква да прилагате заключващ механизъм по време на итерацията. Итераторите запазват препратка към резервния масив в началото на итерацията и не го променят. Следователно е необходима кратка синхронизация, за да се получи съдържанието на масива. Множество нишки могат да имат достъп до колекцията, без да се намесват една в друга. Дори модификацията от множество нишки не търпи спор. Има набор от аналог на този списък с масиви, наречен CopyOnWriterSet , който може да се използва за замяна на синхронизиран Набор при нужда от едновременност.

Бърз пример

В едновременната колекция има много класове. Използването им не е толкова трудно за всеки, запознат с по-старата рамка за събиране. За пълнота, ето пример, който да даде поглед върху употребата му в програмирането на 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.");
         }
      }
   }
}

Заключение

Може би най-голямата полза от използването на едновременните класове за събиране е тяхната мащабируемост и нисък риск. API за едновременна колекция на Java предоставя набор от класове, които са специално проектирани да се справят с едновременни операции. Тези класове са алтернативи на Java Collection Framework и предоставят подобна функционалност, освен с допълнителната поддръжка на паралелност. Следователно кривата на обучение за програмистите, които вече знаят за Java Collection Framework, е почти плоска. Класовете са дефинирани в пакета java.util.concurrent . Тук се опитах да дам общ преглед, за да започнете и да използвам API за колекция, където е необходимо.

Препратки

  • Документация за API на Java
  • Гетц, Брайън и Тим Пайърлс. Работа на паралелност на Java . Пиърсън, 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. Свързване на PowerShell към Salesforce.com

  2. Помощна програма за проверка на клъстер, генерираща голям брой xml файлове във файловата система “/u01”.

  3. Грешки при свързване с база данни или удостоверяване с подвижен тип

  4. Забавление с компресия (columnstore) на много голяма маса – част 1

  5. Попълване на Teradata с реалистични тестови данни De Novo