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

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

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

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

Пример 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();

Ссылки (см. синопсис )

Категория:Шаблоны проектирования