Полное руководство по синхронизации в Java

Опубликовано: 2022-05-20

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

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

В этом руководстве о том, что такое синхронизация в Java , подробно рассматривается концепция синхронизации с примерами.

Оглавление

Что такое синхронизация в Java?

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

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

Синтаксис записи синхронизированного блока

Общий синтаксис для записи синхронизированного блока в Java выглядит следующим образом:

синхронизированный (объект блокировки)

{

// синхронизированные операторы

}

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

Блокировки в Java

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

Изучите онлайн-курсы по разработке программного обеспечения от лучших университетов мира. Участвуйте в программах Executive PG, Advanced Certificate Programs или Master Programs, чтобы ускорить свою карьеру.

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

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

Вот пример синхронизированного метода Java:

//пример синхронизированного метода Java

Таблица классов{

синхронизированный void printTable(int n){//синхронизированный метод

для (целое я = 1; я <= 5; я ++) {

Система.out.println(n*i);

пытаться{

Thread.sleep(400);

} поймать (Исключение e) {System.out.println (e);}

}

}

}

класс MyThread1 расширяет Thread{

Таблица т;

MyThread1 (Таблица т) {

это.т=т;

}

публичный недействительный запуск () {

т.printTable (5);

}

}

класс MyThread2 расширяет Thread{

Таблица т;

MyThread2 (Таблица т) {

это.т=т;

}

публичный недействительный запуск () {

т.printTable (100);

}

}

открытый класс TestSynchronization2 {

public static void main (String args []) {

Table obj = new Table();//только один объект

MyThread1 t1 = новый MyThread1 (объект);

MyThread2 t2 = новый MyThread2 (объект);

t1.старт();

t2.старт();

}

}

Выход:

5

10

15

20

25

100

200

300

400

500

Что происходит без синхронизации?

Теперь давайте посмотрим на предыдущую программу без синхронизации (обратите внимание на отсутствие ключевого слова synchronized).

Таблица классов{

void printTable(int n){//метод не синхронизирован

для (целое я = 1; я <= 5; я ++) {

Система.out.println(n*i);

пытаться{

Thread.sleep(400);

} поймать (Исключение e) {System.out.println (e);}

}

}

}

класс MyThread1 расширяет Thread{

Таблица т;

MyThread1 (Таблица т) {

это.т=т;

}

публичный недействительный запуск () {

т.printTable (5);

}

}

класс MyThread2 расширяет Thread{

Таблица т;

MyThread2 (Таблица т) {

это.т=т;

}

публичный недействительный запуск () {

т.printTable (100);

}

}

класс TestSynchronization1 {

public static void main (String args []) {

Table obj = new Table();//только один объект

MyThread1 t1 = новый MyThread1 (объект);

MyThread2 t2 = новый MyThread2 (объект);

t1.старт();

t2.старт();

}

}

Выход:

5

100

10

200

15

300

20

400

25

500

Как видите, без синхронизации вывод противоречив.

Изучите наши популярные курсы по программной инженерии

Сл. Нет Программы разработки программного обеспечения
1 Магистр компьютерных наук LJMU и IIITB Программа сертификатов кибербезопасности Caltech CTME
2 Учебный курс по полной разработке стека Программа PG в блокчейне
3 Программа Executive Post Graduate Program в области разработки программного обеспечения - специализация в DevOps Просмотреть все курсы по программной инженерии

Типы синхронизации в Java

Чтобы ответить на вопрос , что такое синхронизация потоков в Java , у нас есть два типа синхронизации: синхронизация потоков и синхронизация процессов.

Давайте разберемся, что означает каждый.

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

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

Методы синхронизации в Java

В общем, в Java есть четыре метода синхронизации:

  • Синхронизированные статические методы
  • Синхронизированные методы экземпляра
  • Синхронизированный блок внутри статических методов
  • Синхронизированный блок внутри методов экземпляра

Давайте рассмотрим каждый метод синхронизации Java более подробно.

Синхронизированные статические методы

Здесь мы используем ключевое слово synchronized для обозначения статических методов в Java. Вот пример синхронизированного статического метода Java:

общедоступный статический MyStaticCounter {

частный статический счетчик целых чисел = 0;

общественное статическое синхронизированное недействительное приращение (целое значение) {

количество += значение;

}

}

Синхронизированные методы экземпляра

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

открытый класс MyCounter {

частный счетчик = 0;

общественное синхронизированное недействительное приращение (целое значение) {

this.count += значение;

}

общественное синхронизированное декрементирование недействительным (целое значение) {

this.count -= значение;

}

}

Синхронизированный блок внутри статических методов

Ниже приведен пример, где мы используем синхронизированный блок внутри статического метода:

открытый класс MyClass {

public static void print (строковое сообщение) {

синхронизированный (MyClass.class) {

log.writeln(сообщение);

}

}

}

Синхронизированный блок внутри методов экземпляра

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

общественное недействительное приращение (целое значение) {

синхронизированный (это) {

this.count += значение;

}

}

Необходимость синхронизации в Java

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

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

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

Вывод

Подводя итог, синхронизация в Java гарантирует, что только один поток может получить доступ к общему ресурсу за раз. Мы можем сделать блок или метод синхронизированным, используя ключевое слово synchronized в Java. Когда поток хочет попасть внутрь синхронизированного блока, он должен получить блокировку, а после выхода из блока поток снимает блокировку. Мы можем использовать ключевое слово synchronized либо с методами, либо внутри блока метода.

Не знаете, где выучить Java?

Сертификация PG upGrad, связанная с работой, в области разработки программного обеспечения это то, что вы ищете!

Сертификация PG в области разработки программного обеспечения, связанная с работой, специально разработанная для выпускников и последних курсов upGrad, идеально подходит для тех, кто хочет научиться программировать и получить работу в программном обеспечении начального уровня. Эта 5-месячная онлайн-программа научит лучшим навыкам работы с программным обеспечением, таким как Java, JavaScript, HTML5, DSA, AWS, MERN и многим другим!

В: Почему мы используем синхронизацию в Java?

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

В: Как реализована синхронизация в Java?

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

В: Что такое взаимоблокировка в Java?

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