Что означает «синхронизированный»?

865

У меня есть некоторые вопросы относительно использования и значимости ключевого слова synchronized.

  • Каково значение ключевого слова synchronized?
  • Когда должны быть методы synchronized?
  • Что значит программно и логически?
Показать ещё 1 комментарий
Теги:
multithreading
keyword
synchronized

16 ответов

747
Лучший ответ

Ключевое слово synchronized - все о чтении и записи разных потоков в одни и те же переменные, объекты и ресурсы. Это не тривиальная тема в Java, но вот цитата из Sun:

synchronized методы обеспечивают простую стратегию предотвращения помех потоков и ошибок согласованности памяти: если объект виден более чем одному потоку, все операции чтения или записи в переменные этого объекта выполняются с помощью синхронизированных методов.

В двух словах: если у вас есть два потока, которые читают и пишут в один и тот же "ресурс", скажем, переменную с именем foo, вам нужно убедиться, что эти потоки обращаются к переменной атомарным способом. Без ключевого слова synchronized ваш поток 1 может не увидеть поток изменений 2, внесенный в foo, или, что еще хуже, он может быть изменен только наполовину. Это не будет то, что вы ожидаете логически.

Опять же, это нетривиальная тема в Java. Чтобы узнать больше, изучите темы здесь, в SO и Interwebs:

Продолжайте изучать эти темы, пока имя "Брайан Гетц" не станет постоянно ассоциироваться с термином "параллелизм" в вашем мозгу.

  • 64
    Итак, в основном это ключевое слово Synchronized делает ваши методы поточно-ориентированными?
  • 73
    Ключевое слово synchronized является одним из инструментов, которые делают ваш поток кода безопасным. Простое использование синхронизированного метода или переменной само по себе может или не может помочь. Для понимания правильности параллелизма очень важно иметь базовое понимание модели памяти Java.
Показать ещё 12 комментариев
271

Ну, я думаю, у нас было достаточно теоретических объяснений, поэтому рассмотрим этот код

public class SOP {
    public static void print(String s) {
        System.out.println(s+"\n");
    }
}

public class TestThread extends Thread {
    String name;
    TheDemo theDemo;
    public TestThread(String name,TheDemo theDemo) {
        this.theDemo = theDemo;
        this.name = name;
        start();
    }
    @Override
    public void run() {
        theDemo.test(name);
    }
}

public class TheDemo {
    public synchronized void test(String name) {
        for(int i=0;i<10;i++) {
            SOP.print(name + " :: "+i);
            try{
                Thread.sleep(500);
            } catch (Exception e) {
                SOP.print(e.getMessage());
            }
        }
    }
    public static void main(String[] args) {
        TheDemo theDemo = new TheDemo();
        new TestThread("THREAD 1",theDemo);
        new TestThread("THREAD 2",theDemo);
        new TestThread("THREAD 3",theDemo);
    }
}

Примечание. synchronized блокирует следующий вызов потока методу метода(), пока предыдущее выполнение потока не завершено. Потоки могут получить доступ к этому методу по одному за раз. Без synchronized все потоки могут одновременно обращаться к этому методу.

Когда поток вызывает синхронизированный метод "test" объекта (здесь объект является экземпляром класса "TheDemo" ), он получает блокировку этого объекта, любой новый поток не может вызывать ЛЮБОЙ синхронизированный метод того же самого объекта поскольку предыдущий поток, который приобрел блокировку, не освобождает блокировку.

Аналогичная ситуация возникает, когда вызывается какой-либо статический синхронизированный метод класса. Поток получает блокировку, связанную с классом (в этом случае любой нестационарный синхронизированный метод экземпляра этого класса может быть вызван любым потоком, поскольку этот блокировка уровня объекта по-прежнему доступна). Любой другой поток не сможет вызвать какой-либо статический синхронизированный метод класса, если блокировка уровня класса не освобождается потоком, который в настоящее время удерживает блокировку.

Выход с синхронизированным

THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9

Выход без синхронизации

THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9
  • 5
    Отличный пример, полезно знать теорию, но код всегда более конкретный и полный.
  • 1
    потрясающее объяснение
Показать ещё 8 комментариев
100

Ключевое слово synchronized предотвращает параллельный доступ к блоку кода или объекта несколькими потоками. По умолчанию, Hashtable - synchronized, поэтому только один поток может одновременно обращаться к таблице.

При использовании конструкций non-synchronized, таких как HashMap, вы должны создавать функции безопасности потоков в своем коде, чтобы предотвратить ошибки согласованности памяти.

76

synchronized означает, что в многопоточной среде объект, имеющий synchronized метод (ы)/блок (ы), не позволяет двум потокам обращаться к методу (методам)/блокам (-ам) synchronized кода одновременно. Это означает, что один поток не может читать, пока другой поток обновляет его.

Второй поток вместо этого ожидает, пока первый поток завершит выполнение. Накладные расходы - это скорость, но преимущество заключается в гарантированной согласованности данных.

Если ваше приложение однопоточно, но блоки synchronized не предоставляют преимуществ.

48

Ключевое слово synchronized заставляет поток получать блокировку при вводе метода, так что только один поток может одновременно выполнить этот метод (для данного экземпляра объекта, если он не является статическим методом).

Это часто называют созданием класса потокобезопасным, но я бы сказал, что это эвфемизм. Хотя верно, что синхронизация защищает внутреннее состояние Vector от повреждения, это обычно не помогает пользователю Vector.

Рассмотрим это:

 if (vector.isEmpty()){
     vector.add(data);
 }

Несмотря на то, что задействованные методы синхронизированы, поскольку они блокируются и разблокируются индивидуально, два кэш-приложения с временным временем могут создавать вектор с двумя элементами.

Таким образом, вы также должны синхронизировать свой код приложения.

Поскольку синхронизация на уровне метода является a) дорогой, когда она вам не нужна, и b) недостаточно, когда вам нужна синхронизация, теперь есть несинхронизированные замены (ArrayList в случае Vector).

Совсем недавно был выпущен пакет concurrency с множеством умных утилит, которые заботятся о проблемах с несколькими потоками.

  • 0
    Извините, но у меня есть этот пример, и я не понимаю значения: `Integer i1 = Arrays.asList (1,2,3,4,5) .stream (). FindAny (). Get (); synchronized (i1) {Integer i2 = Arrays.asList (6,7,8,9,10) .parallelStream () .sorted () .findAny (). get (); System.out.println (i1 + "" + i2); } `1. Почему вы вызываете блок в первом экземпляре, и этот вызов не влияет на код? 2. Второй экземпляр будет потокобезопасным, несмотря на вызов блока на первом?
22

Обзор

Синхронизированное ключевое слово в Java имеет отношение к безопасности потоков, то есть когда несколько потоков читают или записывают одну и ту же переменную.
Это может произойти напрямую (путем доступа к одной и той же переменной) или косвенно (с использованием класса, который использует другой класс, который обращается к той же переменной).

Синхронизированное ключевое слово используется для определения блока кода, в котором несколько потоков могут безопасно обращаться к одной и той же переменной.

Deeper

Синтаксически ключевое слово synchronized принимает параметр Object в качестве его (называемый объектом блокировки), за которым следует { block of code }.

  • Когда выполнение встречает это ключевое слово, текущий поток пытается "блокировать/приобретать/владеть" (берет ваш выбор) объект блокировки и выполнять соответствующий блок кода после того, как блокировка была получена.

  • Любая запись в переменные внутри синхронизированного кодового блока гарантированно будет видна для каждого другого потока, который аналогичным образом выполняет код внутри синхронизированного кодового блока с использованием одного и того же объекта блокировки.

  • Только один поток за раз может удерживать блокировку, в течение которого все остальные потоки, пытающиеся получить один и тот же объект блокировки, будут ждать (приостановить их выполнение). Блокировка будет отпущена, когда выполнение завершит синхронизированный блок кода.

Синхронизированные методы:

Добавление ключевого слова synchronized в определение метода равно всему телу метода, который обернут в синхронизированный блок кода, причем объектом блокировки является this (например, методы) и ClassInQuestion.getClass() (для методов класса).

- Метод экземпляра - это метод, который не имеет ключевого слова static.
- Метод класса - это метод с ключевым словом static.

Технические

Без синхронизации не гарантируется, в каком порядке происходит чтение и запись, возможно, оставляя переменную с мусором.
(Например, переменная может содержать половину бит, написанных одним потоком и половиной бит, написанных другим потоком, оставляя переменную в состоянии, которое ни один из потоков не пытался записать, но объединенный беспорядок обоих.)

Недостаточно выполнить операцию записи в потоке до (настенное время) другой поток читает его, потому что аппаратное обеспечение может кэшировать значение переменной, а поток чтения будет видеть кешированное значение вместо того, что был написан на нем.

Заключение

Таким образом, в случае Java вам необходимо следовать модели памяти Java, чтобы убедиться, что ошибки потоковой передачи не выполняются.
Другими словами: используйте синхронизацию, атомные операции или классы, которые используют их для вас под капюшонами.

Источники

http://docs.oracle.com/javase/specs/jls/se8/html/index.html
Спецификация языка Java, 2015-02-13

  • 0
    Извините, но у меня есть этот пример, и я не понимаю значения: `Integer i1 = Arrays.asList (1,2,3,4,5) .stream (). FindAny (). Get (); synchronized (i1) {Integer i2 = Arrays.asList (6,7,8,9,10) .parallelStream () .sorted () .findAny (). get (); System.out.println (i1 + "" + i2); } `1. Почему вы вызываете блок в первом экземпляре, и этот вызов не влияет на код? 2. Второй экземпляр будет потокобезопасным, несмотря на вызов блока на первом?
  • 1
    @ Adryr83 Если у вас есть вопрос, вы можете задать его, разместив новый вопрос. Но так как мы здесь, я разберусь, что я могу (ваш вопрос немного сложен для понимания). Из того, что я могу сказать об этом куске кода, он не содержит ничего, что требует синхронизации. Это вне контекста. Предложение: Если вы можете, попробуйте разделить код на более мелкие отдельные части, а затем найдите ответы на эти вопросы. Гораздо проще пытаться понять маленькие и изолированные проблемы, чем пытаться выяснить один большой блок кода.
18

Подумайте об этом как о турникете, как вы можете найти на футбольном поле. Есть паралисты людей, желающих войти, но на турникете они "синхронизированы". Только один человек за один раз может пройти. Все, кто хочет пройти, будут делать, но им, возможно, придется подождать, пока они не пройдут.

13

Что такое ключевое слово synchronized?

Потоки передаются в основном путем совместного доступа к полям и полям ссылок на объекты. Эта форма коммуникации чрезвычайно эффективна, но допускает два типа ошибок: помехи потоков и ошибки согласованности памяти. Инструмент, необходимый для предотвращения этих ошибок, - это синхронизация.

Синхронизированные блоки или методы предотвращают взаимодействие потоков и обеспечивают постоянство данных. В любой момент времени только один поток может получить доступ к синхронизированному блоку или методу (критический раздел) путем приобретения блокировки. Другие потоки ожидают выхода блокировки для доступа к критическому разделу.

Когда синхронизируются методы?

Методы синхронизируются, когда вы добавляете synchronized в определение или объявление метода. Вы также можете синхронизировать определенный блок кода с помощью метода.

Что означает про грамматически и логически?

Это означает, что только один поток может получить доступ к критическому разделу путем приобретения блокировки. Если этот поток не освободит эту блокировку, все остальные нити придется ждать, чтобы получить блокировку. У них нет доступа для входа в критический раздел без блокировки.

Это невозможно сделать с помощью магии. Ответственность программиста заключается в том, чтобы определить критический раздел в приложении и защитить его соответствующим образом. Java обеспечивает инфраструктуру для защиты вашего приложения, но где и что все разделы, подлежащие охране, несет ответственность программиста.

Подробнее о документации java страница

Внутренние блокировки и синхронизация:

Синхронизация построена вокруг внутреннего объекта, известного как встроенная блокировка или блокировка монитора. Внутренние блокировки играют роль в обоих аспектах синхронизации: принудительный эксклюзивный доступ к состоянию объекта и установление происходит до отношений, которые необходимы для видимости.

Каждый объект имеет связанный с ним встроенный замок. По соглашению поток, который нуждается в эксклюзивном и последовательном доступе к полям объекта, должен получить внутреннюю блокировку объекта перед доступом к ним, а затем освободить внутреннюю блокировку, когда она будет с ними.

Говорят, что поток имеет собственный замок между временем, когда он приобрел блокировку и освободил блокировку. Пока поток владеет встроенной блокировкой, ни один другой поток не может получить одну и ту же блокировку. Другой поток будет блокироваться, когда он попытается получить блокировку.

Когда поток освобождает внутреннюю блокировку, между этим действием и любым последующим приобретением одной и той же блокировки устанавливается связь между ними.

Синхронизация синхронных методов имеет два эффекты:

Во-первых, невозможно, чтобы две вызовы синхронизированных методов на одном объекте чередовали.

Когда один поток выполняет синхронизированный метод для объекта, все другие потоки, которые вызывают синхронизированные методы для одного и того же объекта (приостановить выполнение) до тех пор, пока первый поток не будет выполнен с объектом.

Во-вторых, когда синхронизированный метод завершается, он автоматически устанавливает связь между событиями и последующим вызовом синхронизированного метода для одного и того же объекта.

Это гарантирует, что изменения состояния объекта будут видны для всех потоков.

Ищите другие альтернативы синхронизации в:

Избежать синхронизации (это) в Java?

  • 0
    Извините, но у меня есть этот пример, и я не понимаю значения: `Integer i1 = Arrays.asList (1,2,3,4,5) .stream (). FindAny (). Get (); synchronized (i1) {Integer i2 = Arrays.asList (6,7,8,9,10) .parallelStream () .sorted () .findAny (). get (); System.out.println (i1 + "" + i2); } `1. Почему вы вызываете блок в первом экземпляре, и этот вызов не влияет на код? 2. Второй экземпляр будет потокобезопасным, несмотря на вызов блока на первом?
6

Вот объяснение из Учебников Java.

Рассмотрим следующий код:

public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}

если count является экземпляром SynchronizedCounter, то синхронизация этих методов имеет два эффекта:

  • Во-первых, невозможно выполнить два вызова синхронизированных методов для одного и того же объекта. Когда один поток выполняет синхронизированный метод для объекта, все другие потоки, которые вызывают синхронизированные методы для того же блока объекта (приостанавливают выполнение), пока первый поток не завершится с объектом.
  • Во-вторых, при выходе из синхронизированного метода он автоматически устанавливает отношение "до и после" с любым последующим вызовом синхронизированного метода для того же объекта. Это гарантирует, что изменения состояния объекта видны всем потокам.
6

В моем понимании синхронизировано в основном означает, что компилятор пишет monitor.enter и monitor.exit вокруг вашего метода. Как таковой он может быть потокобезопасным в зависимости от того, как он используется (я имею в виду, что вы можете написать объект с синхронизированными методами, который не является потокобезопасным в зависимости от того, что делает ваш класс).

5

Synchronized normal method эквивалентный Synchronized statement (используйте это)

class A {
    public synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(this) {
             // all function code
        }
    } 
}

Synchronized static method эквивалентный Synchronized statement (используйте класс)

class A {
    public static synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(A.class) {
             // all function code
        }
    } 
}

Синхронизированный оператор (с использованием переменной)

class A {
    private Object lock1 = new Object();

    public void methodA() {
        synchronized(lock1 ) {
             // all function code
        }
    } 
}

Для synchronized у нас есть как Synchronized Methods и Synchronized Statements. Однако Synchronized Methods похож на Synchronized Statements поэтому нам просто нужно понять Synchronized Statements.

=> В основном мы будем иметь

synchronized(object or class) { // object/class use to provides the intrinsic lock
   // code 
}

Вот 2 думаю что помогите пониманию synchronized

  • Каждый объект/класс имеет intrinsic lock связанную с ним.
  • Когда поток вызывает synchronized statement, он автоматически получает intrinsic lock для объекта этого synchronized statement's и освобождает ее при возврате метода. Пока потоку принадлежит intrinsic lock, НИКАКОЙ другой поток не может получить ТОТ ЖЕ блокировку => безопасный для потока.

=> Когда thread A вызывает synchronized(this){//code 1} => весь код блока (внутри класса), в котором synchronized(this) и весь synchronized normal method (внутри класса) заблокирован из-за ЖЕ блокировки. Он будет выполнен после разблокировки thread A ("//код 1" завершен).

Это поведение похоже на synchronized(a variable){//code 1} или synchronized(class).

SAME LOCK => lock (не зависит от того, какой метод? Или какие операторы?)

Использовать синхронизированный метод или синхронизированные операторы?

Я предпочитаю synchronized statements потому что они более расширяемы. Например, в будущем вам нужно синхронизировать только часть метода. Например, у вас есть 2 синхронизированных метода, и они не имеют никакого отношения друг к другу, однако, когда поток запускает метод, он блокирует другой метод (это можно предотвратить с помощью synchronized(a variable)).

Однако применить синхронизированный метод очень просто, а код выглядит просто. Для некоторого класса существует только 1 синхронизированный метод или все синхронизированные методы в классе имеют отношение друг к другу => мы можем использовать synchronized method чтобы сделать код более коротким и простым для понимания

Заметка

(это не относится ко многим synchronized, это отличается между объектом и классом или не является статическим и статическим).

  • Когда вы используете synchronized или обычный метод или synchronized(this) или synchronized(non-static variable) он будет синхронизироваться на основе каждого экземпляра объекта.
  • Когда вы используете synchronized или статический метод или synchronized(class) или synchronized(static variable) он будет синхронизирован на основе класса

Ссылка

https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

Надеюсь, это поможет

  • 0
    Извините, но у меня есть этот пример, и я не понимаю значения: `Integer i1 = Arrays.asList (1,2,3,4,5) .stream (). FindAny (). Get (); synchronized (i1) {Integer i2 = Arrays.asList (6,7,8,9,10) .parallelStream () .sorted () .findAny (). get (); System.out.println (i1 + "" + i2); } `1. Почему вы вызываете блок в первом экземпляре, и этот вызов не влияет на код? 2. Второй экземпляр будет потокобезопасным, несмотря на вызов блока на первом?
4

Какие другие ответы отсутствуют, это один важный аспект: барьеры памяти. Синхронизация потоков в основном состоит из двух частей: сериализации и видимости. Я советую всем google "барьер памяти jvm", поскольку это нетривиальная и чрезвычайно важная тема (если вы изменяете общие данные, к которым обращаются несколько потоков). Сделав это, я советую посмотреть классы пакетов java.util.concurrent, которые помогают избежать использования явной синхронизации, что, в свою очередь, помогает поддерживать простые и эффективные программы, возможно, даже предотвращая взаимоблокировки.

Одним из таких примеров является ConcurrentLinkedDeque. Вместе с шаблон команды он позволяет создавать высокоэффективные рабочие потоки, набирая команды в параллельную очередь - не требуется явная синхронизация, нет взаимоблокировок возможно, нет явного сна(), необходимо просто опросить очередь, вызвав take().

Вкратце: "синхронизация памяти" происходит неявно при запуске потока, поток заканчивается, вы читаете переменную volatile, вы разблокируете монитор (оставляете синхронизированный блок/функцию) и т.д. Эта "синхронизация" влияет (в смысл "флеши" ), все записи делаются до этого конкретного действия. В случае вышеупомянутого ConcurrentLinkedDeque документация "говорит":

Эффекты согласованности памяти: как и в других параллельных коллекциях, действий в потоке до помещения объекта в ConcurrentLinkedDeque произойдет до действия после доступа или удаление этого элемента из ConcurrentLinkedDeque в другом нить.

Это неявное поведение является несколько пагубным аспектом, потому что большинство программистов Java, не имеющих большого опыта, просто возьмут много, как указано из-за этого. И затем внезапно наткнуться на этот поток после того, как Java не делает то, что "предполагается" делать в производстве, где есть другая рабочая нагрузка, и довольно сложно протестировать проблемы concurrency.

3

Синхронизированное просто означает, что несколько потоков, если они связаны с одним объектом, могут предотвратить загрязнение чтения и записи, если для конкретного объекта используется синхронизированный блок. Чтобы дать вам больше ясности, давайте возьмем пример:

class MyRunnable implements Runnable {
    int var = 10;
    @Override
    public void run() {
        call();
    }

    public void call() {
        synchronized (this) {
            for (int i = 0; i < 4; i++) {
                var++;
                System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
            }
        }
    }
}

public class MutlipleThreadsRunnable {
    public static void main(String[] args) {
        MyRunnable runnable1 = new MyRunnable();
        MyRunnable runnable2 = new MyRunnable();
        Thread t1 = new Thread(runnable1);
        t1.setName("Thread -1");
        Thread t2 = new Thread(runnable2);
        t2.setName("Thread -2");
        Thread t3 = new Thread(runnable1);
        t3.setName("Thread -3");
        t1.start();
        t2.start();
        t3.start();
    }
}

Мы создали два объекта класса MyRunnable, а runnable1 - с потоком 1 и потоком 3, а runnable2 - только с потоком 2. Теперь, когда t1 и t3 запускаются без использования синхронизации, вывод PFB, который предполагает, что оба потока 1 и 3 одновременно влияют на значение var, где для потока 2 var имеет свою собственную память.

Without Synchronized keyword

    Current Thread Thread -1 var value 11
    Current Thread Thread -2 var value 11
    Current Thread Thread -2 var value 12
    Current Thread Thread -2 var value 13
    Current Thread Thread -2 var value 14
    Current Thread Thread -1 var value 12
    Current Thread Thread -3 var value 13
    Current Thread Thread -3 var value 15
    Current Thread Thread -1 var value 14
    Current Thread Thread -1 var value 17
    Current Thread Thread -3 var value 16
    Current Thread Thread -3 var value 18

Используя Synchronzied, поток 3 ожидает завершения потока 1 во всех сценариях. Имеются две блокировки: одна на runnable1, совместно используемая нитью 1 и потоком 3, а другая на runnable2, совместно используемая только потоком.

Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -1 var value 12
Current Thread Thread -2 var value 12
Current Thread Thread -1 var value 13
Current Thread Thread -2 var value 13
Current Thread Thread -1 var value 14
Current Thread Thread -2 var value 14
Current Thread Thread -3 var value 15
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 17
Current Thread Thread -3 var value 18
  • 0
    Синхронизированный означает еще больше: он оказывает глубокое влияние на барьер памяти.
2

синхронизированный простой означает, что два потока не могут одновременно обращаться к блоку/методу. Когда мы говорим, что любой блок/метод класса синхронизирован, это означает, что только один поток может обращаться к ним за раз. Внутренний поток, который пытается получить к нему доступ, сначала блокирует этот объект, и пока эта блокировка недоступна, ни один другой поток не может получить доступ к любому из синхронизированных методов/блоков этого экземпляра класса.

Обратите внимание, что другой поток может получить доступ к методу того же объекта, который не определен для синхронизации. Поток может освободить блокировку, вызвав

Object.wait()
1

Синхронизация: ArrayList не синхронизирован, что означает, что в ArrayList одновременно могут работать несколько потоков. Напр. если один поток выполняет операцию добавления в ArrayList, может быть другой поток, выполняющий операцию удаления в ArrayList одновременно в многопоточной среде.

в то время как вектор синхронизирован. Это означает, что если один поток работает над Vector, ни один другой поток не сможет его удержать. В отличие от ArrayList, только один поток может выполнять операцию над вектором за раз

-5

synchronized - это ключевое слово в Java, которое используется для совершения до отношения в многопоточной среде, чтобы избежать несогласованности памяти и ошибки вмешательства потока.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню