Перед прочтением этой статьи вы можете сначала прочитать « Введение и использование многопоточного атомного пакета Java » , чтобы узнать о соответствующем содержании атомного пакета.
1. Что является атомным?
Слово «Атомное» имеет какое -то отношение к атомам, которое когда -то считалось единицей наименьшего вещества. Атомный в компьютере означает, что его нельзя разделить на несколько частей. Если часть кода считается атомным, это означает, что код не может быть прерван во время выполнения. Вообще говоря, атомные инструкции предоставляются аппаратным обеспечением и предоставляются программным обеспечением для реализации атомных методов (поток не будет прерван после входа в метод до завершения его выполнения)
На платформе x86 процессор предоставляет средства для блокировки шины во время выполнения инструкции. На чипе процессора есть лидерство #hlockpin. Если префикс «блокировка» добавлена в инструкцию в программе языка сборки, код машины сборки приведет к снижению потенциала #hlockpin при выполнении этой инструкции и отпустит его до конца этой инструкции, тем самым блокируя шину. Таким образом, другие процессоры на той же шине не могут получить доступ к памяти через шину на данный момент, обеспечивая атомацию этой инструкции в многопроцессорной среде.
2. Атомные переменные в java.util.concurrent
Будь то прямые или косвенные, почти все классы в пакете java.util.concurrent используют атомные переменные, а не синхронизация. Такие классы, как comproundlinkedqueue, также используют атомные переменные для непосредственного реализации алгоритма без ожидания, в то время как такие классы, как Comparrenthashmap, используют reentrantlock для блокировки при необходимости. Затем Reentrantlock использует атомные переменные для поддержания очереди резьбы в ожидании блокировки.
Без улучшений JVM в JDK5.0 эти классы не будут построены, которые разоблачают (для библиотеки классов, а не в пользовательском классе) интерфейсы для доступа к примидам синхронизации оборудования. Классы атомной переменной и другие классы в java.util.concurrent затем обнажают эти функции в класс пользователя
атомный класс java.util.concurrent.atomic
Этот пакет предоставляет набор атомных классов. Основная особенность заключается в том, что в многопоточной среде, когда несколько потоков выполняют методы, содержащиеся в экземплярах этих классов одновременно, это исключительно, то есть, когда поток входит в метод и выполняет в нем инструкции, его не будут прерываться другими потоками, а другие потоки похожи на спиновые блокировки. Пока метод не будет выполнен, JVM выберет другой поток из очереди ожидания для ввода. Это просто логическое понимание. Фактически, он реализован с помощью соответствующих аппаратных инструкций и не будет блокировать потоки (или он просто заблокирован на уровне аппаратного обеспечения). Классы можно разделить на 4 группы
Atomicboolean, Atomicinteger, Atomiclong, Atomicreference
Atomicintegerarray, Atomiclongarray
Atomiclongfieldupdater, Atomicintegerfieldupdater, Atomicreferencefieldupdater
AtomicMarkAbleReerference, AtomicStampedReference, AtomicReerenceArray
Среди них атомный, атомный, атомный, атомный, атомареференция похожи.
Прежде всего, Atomicboolean, Atomicinteger, Atomiclong, Atomicreference Внутренние API схожи: возьмите пример AtomicReference
Создайте безопасную ветку стека с AtomicReference
открытый класс LinkedStack <t> {private atomicReference <node <t >> Stacks = new AtomicReference <node <t >> (); public t push (t e) {node <t> oldnode, newnode; в то время как (true) {// обработка здесь очень особенная, и это должно быть так. OldNode = stacks.get (); newNode = new Node <t> (e, oldnode); if (stacks.compareandset (oldnode, newnode)) {return e;}}} public t pop () {node <t> oldnode, newnode; while (true) {oldnode = stacks.get ();); (Stacks.compareAndset (oldnode, newnode)) {return oldnode.object;}}} частный статический конечный узел класса <t> {private t object; private node <t> next; private node (t object, node <t> next) {this.object = object; this.next =}}}}}}}}Затем сосредоточьтесь на атомном обновлении поля.
Atomicintegerfieldupdater <t>/atomiclongfieldupdater <t>/atomicreferencefieldupdater <t, v> - значение поля, основанное на отражении.
Соответствующий API также очень прост, но он также имеет некоторые ограничения.
(1) Поле должно быть такого типа летучим! Что является изменчивым? Пожалуйста, проверьте « Подробное объяснение летучих ключевых слов на Java »
(2) Тип описания поля (модификатор public/protected/default/private) согласуется с взаимосвязи между вызывающим и полевым полем объекта. То есть абонент может напрямую эксплуатировать поле объекта, а затем отражать и выполнять атомные операции. Однако для полей родительского класса подкласс не может работать напрямую, хотя подкласс может получить доступ к полям родительского класса.
(3) Это может быть только переменная экземпляра, а не переменная класса, то есть она не может добавить статические ключевые слова.
(4) Это может быть только модифицированные переменные, и это не может быть превращено в конечные переменные, поскольку семантика финала неизменена. Фактически, семантика окончательного и нестабильного конфликта, и эти два ключевых слова не могут существовать одновременно.
(5) Для Atomicintegerfieldupdater и Atomiclongfieldupdater они могут изменить только поля INT/Long Type и не могут изменить свой тип обертки (целое число/long). Если вы хотите изменить тип обертывания, вам нужно использовать AtomicReferenceFieldupdater.
Метод работы описан в следующем примере.
Import java.util.concurrent.atomic.atomicintegerfieldupdater; открытый класс Atomicintegerfieldupdaterdemo {class demodata {public volatile int value1 = 1; volatile int value2 = 2; защищенная изменчивая int value3 = 3; Crivate Valatile value4 = 4;} atomicIntegerupaterupdater. FieldName) {return atomicintegerfieldupdater.newupdater (demodata.class, fieldname);} void doit () {demodata data = new demodata (); System.out.println ("1 ==>"+getupdater ("value1"). getandset (data, 10); "+getupdater (" value2 "). IgrmentAndget (data)); System.out.println (" 2 ==> "+getUpdater (" value3 "). DementemAndget (data)); System.out.println (" true ==> "+getupdater (" value4 "). Сравнение (Data Data, 5); {Atomicintegerfieldupdaterdemo demo = new atomicintegerfieldupdaterdemo (); demo.doit ();}}В приведенном выше примере значение поля3/значение4 демодаты не видно классу Atomicintegerfieldupdaterdemo, поэтому его значение не может быть напрямую изменено с помощью отражения.
Пара <объекта, Boolean>, описанная классом AtomicMarkAbleReerference, может атомно изменить значение объекта или логического. Эта структура данных более полезна в некоторых описаниях кэша или состояний. Эта структура может эффективно повысить пропускную способность при изменении объекта/логического языка индивидуально или одновременно.
Класс AtomicStampedReference поддерживает ссылки на объекты с целочисленными «флагами» и может быть обновлен атомно. По сравнению с <объектом, Boolean> класса AtomicMarkAbleReerference, AtomicSmapedReference поддерживает структуру данных, аналогичную <объекта, int>, которая на самом деле является одновременным количеством объектов (ссылки). Но в отличие от AtomicInteger, эта структура данных может нести ссылку на объект и может выполнять атомные операции на этом объекте и одновременно учитывать.
«Проблема ABA» будет упомянута в конце этой статьи, а AtomicMarkAbleReerference/AtomicStampedReference полезен для решения «Проблема ABA».
Iii. Роль атомного
Это позволяет разборотью отдельных данных.
Создайте сложный, без блокировки кода с использованием атомных классов
Обычно считается, что доступ к 2 или более атомной переменных (или выполнение 2 или более операций по одной атомной переменной), как правило, требует синхронизации, чтобы эти операции могли использоваться в качестве атомной единицы.
Без блокировки и алгоритма ожидания
Алгоритмы параллелистики, основанные на CAS (ComparandsWAP), называются алгоритмами без блокировки, потому что потоки больше не должны ждать блокировки (иногда называемые мутекс или критические части, в зависимости от терминологии платформы потока). Успешная операция CAS успешна или не удается, в любом случае она завершается в течение предсказуемого времени. Если CAS выходит из строя, абонент может повторно повторно операции CAS или взять другие подходящие операции.
Если каждый поток продолжает работать, когда другие потоки задерживаются (или даже не удалены), можно сказать, что алгоритм без ожидания. Напротив, алгоритм без блокировки требует, чтобы только определенный поток всегда выполнял работу. (Другое определение отсутствия ожидания состоит в том, чтобы убедиться, что каждый поток правильно вычисляет свои собственные операции в своих ограниченных этапах, независимо от операций, времени, кроссовера или скорости других потоков. Этот предел может быть функцией того, что количество потоков в системе; например, если есть 10 потоков, каждый поток выполняет каскантер. Инкра ().)
За последние 15 лет люди провели обширные исследования алгоритмов без ожидания и без блокировки (также известных как неблокирующие алгоритмы), и многие люди обнаружили неблокирующие алгоритмы в общих структурах данных. Неблокирующие алгоритмы широко используются в операционной системе и уровне JVM, выполняя такие задачи, как потоки и планирование процессов. Хотя их реализация является более сложной, у них есть много преимуществ по сравнению с альтернативными алгоритмами, основанными на блокировке: они могут избежать таких опасностей, как приоритетная инверсия и тупик, конкуренция дешевле, координация происходит на более мелком уровне детализации, что обеспечивает более высокую степень параллелизма и так далее.
Общий:
Не блокирующий счетчик
Неблокирующий стек concurrentStack
Не блокирующий связанный список concurrentLinkedQueue
Вопросы ABA:
Потому что перед изменением V V, CAS в основном спрашивает, «является ли значение V все еще», прежде чем читать V впервые и выполнять операции CAS на V, изменяя значение с A на B, а затем обратно в Alling Ally Base на основе CAS. В этом случае операция CAS будет успешной, но в некоторых случаях результат может не быть тем, что вы ожидали. Этот тип проблемы называется ABA -проблемой, которая обычно обрабатывается путем ассоциации тега или номера версии с каждым значением, которое будет выполнено в операции CAS, и атомно обновлять значения и теги. Класс AtomicStampedReference поддерживает этот метод.
Суммировать
Выше приведено все подробное объяснение этой статьи об эксплуатации атомных переменных и атомных классов в многопоточном атомном пакете Java. Я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на этот сайт:
Программирование Java: многопоточный тупик и связь между потоками простые коды
Java многопоточный программирование небольшой пример имитирует системы парковки
Краткое обсуждение преимуществ и примеров кода многопоточного чтения Java
Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это.