Single Thread Execution

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

Перейти к: навигация, поиск

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

Содержание

Мотивы

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

Следствия

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

    Пример реализации

    Пример C#

    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();
            }
        }
    }
    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;
                }
            }
        }
    }
    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));
            }
        }
    }
    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();
            }
        }
    }

    Ссылки

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


  • Личные инструменты

    Served in 0.036 secs.