Single Thread Execution

Материал из Seo Wiki - Поисковая Оптимизация и Программирование
Перейти к навигацииПерейти к поиску

Однопоточное выполнение (англ. Single Threaded Execution) — известный также под названием англ. Critical Section. Шаблон проектирования препятствующий конкурентному вызову метода, тем самым запрещая параллельное выполнение этого метода.

Мотивы

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

Следствия

  • + Обеспечивается безопасность потоков
  • - Производительность может быть снижена
  • - Возможно взаимная блокировка
  • Пример реализации

    Пример C#

    <source lang="csharp"> using System; using System.Threading;

    namespace Digital_Patterns.Concurrency.Single_Thread_Execution {

       /// <summary>
       /// Экземпляры класса <see cref="TrafficSensor"/> связаны с сенсором движения
       /// транспорта, который фиксирует прохождение машиной некоторого места на
       /// полосе движения.
       /// </summary>
       class TrafficSensor
       {
           private static Int32 mID = 0;
    
           private ITrafficObserver _observer;
    
           public Boolean IsRun { get; set; }
    
           private Int32 _id;
    


           /// <summary>
           /// Конструктор
           /// </summary>
           /// <param name="observer">Объект, предназначеный для оповещения о том, что сенсор
           /// движения транспорта, связанный с этим объектом,
           /// обнаруживает проходящую машину.</param>
           public TrafficSensor(ITrafficObserver observer)
           {
               _id = ++mID;
               _observer = observer;
               IsRun = true;
               new Thread(Run).Start();
           }
    
           /// <summary>
           /// Общая логика для потока этого объекта
           /// </summary>
           private void Run()
           {
               while (IsRun)
               {
                   motitorSensor();
               }
           }
           
           private static Random mRnd = new Random();
           /// <summary>
           /// Этом метод вызывает метод detect объекта, когда
           /// связанный с ним сенсор движения транспорта фиксирует 
           /// проходящую машину
           /// </summary>
           private void motitorSensor()
           {
               //TODO Something
               Thread.Sleep(mRnd.Next(1000));
               var msg = System.Reflection.MethodInfo.GetCurrentMethod().Name;
               Console.WriteLine(String.Format(@"{0} {1} +1", _id, msg));
               
               detect();
           }
    
           /// <summary>
           /// Этот метод вызывается методом <see cref="motitorSensor"/>, 
           /// чтобы сообщить о прохождении транспортного средства 
           /// наблюдателю этого объекта
           /// </summary>
           private void detect()
           {
               _observer.vehiclePassed();
           }
    
           /// <summary>
           /// Классы должны реализовывать этот интерфейс, 
           /// чтобы объект <see cref="TrafficSensor"/> мог сообщить им о прохождении 
           /// машин
           /// </summary>
           public interface ITrafficObserver
           {
               /// <summary>
               /// Вызывается тогда, когда <see cref="TrafficSensor"/> фиксирует 
               /// проходящее транспортное средство.
               /// </summary>
               void vehiclePassed();
           }
       }
    

    } </source>

    <source lang="csharp"> using System;

    namespace Digital_Patterns.Concurrency.Single_Thread_Execution {

       /// <summary>
       /// Экземпляры класса <see cref="TrafficSensorController"/> хранят текущее
       /// общее количество машин, прошедших мимо сенсоров движения транспорта,
       /// связанных с экзепляром.
       /// </summary>
       class TrafficSensorController : TrafficSensor.ITrafficObserver
       {
           private Int32 _vehicleCount = 0;
    
           /// <summary>
           /// Этот метод вызывается в том случае, когда сенсор движения
           /// траспорта фиксирует прохождение машины. Он увеличивает 
           /// значение счетчика машин на единицу.
           /// </summary>
           public void vehiclePassed()
           {
               lock (this)
               {
                   ++_vehicleCount;
               }
           }
    
           /// <summary>
           /// Сбрасывает счетчик машин в нуль
           /// </summary>
           /// <returns></returns>
           public Int32 GetAndClearCount()
           {
               lock (this)
               {
                   Int32 count = _vehicleCount;
                   _vehicleCount = 0;
                   return count;
               }
           }
       }
    

    } </source>

    <source lang="csharp"> using System; using System.Threading;

    namespace Digital_Patterns.Concurrency.Single_Thread_Execution {

       /// <summary>
       /// Экземпляры класса <see cref="TrafficTransmitter"/> отвечают за передачу
       /// занчения, определяющего количество машин, проходящих через данное место
       /// дороги за одну минуту.
       /// </summary>
       class TrafficTransmitter
       {
           private TrafficSensorController _conrtoller;
           private Thread _myThread;
    
           public Boolean IsRun { get; set; }
    
           /// <summary>
           /// Конструктор
           /// </summary>
           /// <param name="conrtoller">От <see cref="TrafficSensorController"/> этот объект
           /// будет получать значение счетчика количества прошедших 
           /// машин</param>
           public TrafficTransmitter(TrafficSensorController conrtoller)
           {
               _conrtoller = conrtoller;
    
               _myThread = new Thread(Run);
               IsRun = true;
               _myThread.Start();
           }
    
           /// <summary>
           /// Передает значение счетчика количества машин, прошедщих 
           /// за промежуток времени
           /// </summary>
           private void Run()
           {
               while (IsRun)
               {
                   Thread.Sleep(10000);
                   Transmit(_conrtoller.GetAndClearCount());
               }
           }
    
           private void Transmit(Int32 count)
           {
               //TODO Something
               var msg = System.Reflection.MethodInfo.GetCurrentMethod().Name;
               Console.WriteLine(String.Format(@"{0} {1}", msg, count));
           }
       }
    

    } </source>

    <source lang="csharp"> using System; using Digital_Patterns.Concurrency.Single_Thread_Execution;

    namespace Digital_Patterns {

       class Program
       {
           static void Main(string[] args)
           {
               var controller = new TrafficSensorController();
               var transmitter = new TrafficTransmitter(controller);
    
               Console.WriteLine(@"Press any key for start, and press again for finish");
               Console.ReadKey();
    
               var sensor1 = new TrafficSensor(controller);
               var sensor2 = new TrafficSensor(controller);
    
               Console.ReadKey();
    
               sensor1.IsRun = false;
               sensor2.IsRun = false;
               transmitter.IsRun = false;
               Console.WriteLine();
           }
       }
    

    } </source>

    Ссылки

    • Mark Grand Patterns in Java Volume 1: A Catalog of Reusable Design Patterns Illustrated with UML. — Wiley & Sons, 1998. — 480 с. — ISBN 0471258393 (см. синопсис (англ.))


    Если вам нравится SbUP.com Сайт, вы можете поддержать его - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 и ещё....