23:45
Урок 25: Синхронизация потоков

Курс по программированию на Java

Урок 25: Синхронизация потоков

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

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

Методы могут быть объявлены как synchronized, что гарантирует, что только один поток может выполнять этот метод в определенный момент времени:

class Counter {
 private int count = 0;

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

 public int getCount() {
 return count;
 }
}

public class SynchronizedMethodExample {
 public static void main(String[] args) {
 Counter counter = new Counter();
 
 Thread t1 = new Thread(() -> {
 for (int i = 0; i < 1000; i++) {
 counter.increment();
 }
 });
 
 Thread t2 = new Thread(() -> {
 for (int i = 0; i < 1000; i++) {
 counter.increment();
 }
 });
 
 t1.start();
 t2.start();
 
 try {
 t1.join();
 t2.join();
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 
 System.out.println("Count: " + counter.getCount());
 }
}

Результат выполнения

Count: 2000

Синхронизированные блоки

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

class Counter {
 private int count = 0;

 public void increment() {
 synchronized (this) {
 count++;
 }
 }

 public int getCount() {
 return count;
 }
}

public class SynchronizedBlockExample {
 public static void main(String[] args) {
 Counter counter = new Counter();
 
 Thread t1 = new Thread(() -> {
 for (int i = 0; i < 1000; i++) {
 counter.increment();
 }
 });
 
 Thread t2 = new Thread(() -> {
 for (int i = 0; i < 1000; i++) {
 counter.increment();
 }
 });
 
 t1.start();
 t2.start();
 
 try {
 t1.join();
 t2.join();
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 
 System.out.println("Count: " + counter.getCount());
 }
}

Результат выполнения

Count: 2000

Упражнения

Упражнение 1: Синхронизация метода

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

Решение:

class BankAccount {
 private int balance = 1000;

 public synchronized void deposit(int amount) {
 balance += amount;
 }

 public synchronized void withdraw(int amount) {
 balance -= amount;
 }

 public int getBalance() {
 return balance;
 }
}

public class BankExample {
 public static void main(String[] args) {
 BankAccount account = new BankAccount();
 
 Thread t1 = new Thread(() -> {
 for (int i = 0; i < 10; i++) {
 account.deposit(100);
 System.out.println("Deposited 100, balance: " + account.getBalance());
 }
 });
 
 Thread t2 = new Thread(() -> {
 for (int i = 0; i < 10; i++) {
 account.withdraw(100);
 System.out.println("Withdrew 100, balance: " + account.getBalance());
 }
 });
 
 t1.start();
 t2.start();
 
 try {
 t1.join();
 t2.join();
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 
 System.out.println("Final balance: " + account.getBalance());
 }
}

Объяснение: Программа создает объект BankAccount и два потока, которые одновременно вносят и снимают деньги с счета. Методы deposit и withdraw синхронизированы, что предотвращает одновременное изменение баланса счета несколькими потоками.

Упражнение 2: Синхронизация блока

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

Решение:

class SharedCounter {
 private int count = 0;

 public void increment() {
 synchronized (this) {
 count++;
 }
 }

 public int getCount() {
 return count;
 }
}

public class SynchronizedBlockExample {
 public static void main(String[] args) {
 SharedCounter counter = new SharedCounter();
 
 Thread t1 = new Thread(() -> {
 for (int i = 0; i < 1000; i++) {
 counter.increment();
 }
 });
 
 Thread t2 = new Thread(() -> {
 for (int i = 0; i < 1000; i++) {
 counter.increment();
 }
 });
 
 t1.start();
 t2.start();
 
 try {
 t1.join();
 t2.join();
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 
 System.out.println("Final count: " + counter.getCount());
 }
}

Объяснение: Программа создает объект SharedCounter и два потока, которые одновременно увеличивают значение счетчика. Для синхронизации используется блок synchronized внутри метода increment.

Категория: Java | Просмотров: 83 | Добавил: Admin | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *: