Рубрики

Синхронизировано в Java

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

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

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

Ниже приводится общая форма синхронизированного блока:

// Only one thread can execute at a time. 
// sync_object is a reference to an object
// whose lock associates with the monitor. 
// The code is said to be synchronized on
// the monitor object
synchronized(sync_object)
{
   // Access shared variables and other
   // shared resources
}

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

Ниже приведен пример многопоточности с синхронизированным.

// Java-программа для демонстрации работы
// синхронизирован.

import java.io.*;

import java.util.*;

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

class Sender

{

    public void send(String msg)

    {

        System.out.println("Sending\t"  + msg );

        try

        {

            Thread.sleep(1000);

        }

        catch (Exception e)

        {

            System.out.println("Thread  interrupted.");

        }

        System.out.println("\n" + msg + "Sent");

    }

}

  
// Класс для отправки сообщения с использованием потоков

class ThreadedSend extends Thread

{

    private String msg;

    Sender  sender;

  

    // Получает объект сообщения и строку

    // сообщение для отправки

    ThreadedSend(String m,  Sender obj)

    {

        msg = m;

        sender = obj;

    }

  

    public void run()

    {

        // Только одна нить может отправить сообщение

        // вовремя.

        synchronized(sender)

        {

            // синхронизируем объект snd

            sender.send(msg);

        }

    }

}

  
// Класс водителя

class SyncDemo

{

    public static void main(String args[])

    {

        Sender snd = new Sender();

        ThreadedSend S1 =

            new ThreadedSend( " Hi " , snd );

        ThreadedSend S2 =

            new ThreadedSend( " Bye " , snd );

  

        // Запускаем два потока типа ThreadedSend

        S1.start();

        S2.start();

  

        // ждем окончания потоков

        try

        {

            S1.join();

            S2.join();

        }

        catch(Exception e)

        {

            System.out.println("Interrupted");

        }

    }

}

Выход:

 Отправка привет 

 Привет отправлено
Отправка пока 

 Пока отправлено 

Вывод один и тот же каждый раз, когда мы запускаем программу.

В приведенном выше примере мы выбрали синхронизацию объекта Sender внутри метода run () класса ThreadedSend. С другой стороны, мы можем определить весь блок send () как синхронизированный, и он даст тот же результат. Тогда нам не нужно синхронизировать объект Message внутри метода run () в классе ThreadedSend.

// Альтернативная реализация для демонстрации
// что мы можем использовать синхронизированный с методом также.

class Sender 

{

    public synchronized void send(String msg)

    {

        System.out.println("Sending\t" + msg );

        try 

        {

            Thread.sleep(1000);

        

        catch (Exception e) 

        {

            System.out.println("Thread interrupted.");

        }

        System.out.println("\n" + msg + "Sent");

    }

}

Мы не всегда должны синхронизировать весь метод. Иногда предпочтительно синхронизировать только часть метода . Синхронизированные блоки Java внутри методов делают это возможным.

// Еще одна альтернативная реализация для демонстрации
// синхронизированный может использоваться только с частью
// метод

class Sender 

{

    public void send(String msg)

    {

        synchronized(this)

        {

            System.out.println("Sending\t" + msg );

            try 

            {

                Thread.sleep(1000);

            

            catch (Exception e) 

            {

                System.out.println("Thread interrupted.");

            }

            System.out.println("\n" + msg + "Sent");

        }

    }

}

Эта статья предоставлена Souradeep Barua . Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме

Рекомендуемые посты:

Синхронизировано в Java

0.00 (0%) 0 votes