- •1. Назначение языка
- •2. Способы использования языка
- •3. Нотация языка uml
- •Виды диаграмм uml
- •5. Диаграмма прецедентов (use case diagram)
- •6. Диаграмма классов (class diagram)
- •7. Диаграмма объектов (object diagram)
- •8. Диаграмма последовательностей (sequence diagram)
- •9. Диаграмма взаимодействия (кооперации, collaboration diagram)
- •10. Диаграмма состояний (statechart diagram)
- •11. Диаграмма активности (деятельности, activity diagram)
- •12. Диаграмма развертывания (deployment diagram)
- •13. Ооп и последовательность построения диаграмм
- •14. Отображение класса и его элементов на диаграмме uml
- •15. Способы использования объектов класса
- •16. Моделирование наследования в uml
- •17. Отношения между классами
- •18. Отношение зависимости между классами
- •19. Отношение ассоциации между классами
- •20. Композиция и агрегация классов
- •21. Сравнение диаграмм активностей и блок-схем
- •22. Моделирование процессов диаграммами активности
- •23. Моделирование операций диаграммами активности
- •24. Правила построения диаграммам активности
- •Составление перечня деятельностей в системе
- •Принятие решения о необходимости построения диаграммы деятельностей
- •25. Диаграмма кооперации
- •26. Диаграмма последовательностей как диаграмма взаимодействия
- •27. Диаграмма кооперации как альтернатива диаграмм последовательностей
- •28. Диаграмма кооперации как диаграмма взаимодействий объектов
- •29. Типы сообщений: синхронные, асинхронные и ответные, потерянные и найденные.
- •30. Уровни экземпляров и спецификации в диаграммах кооперации
- •31. Мультиобъекты, композитные и активные объекты в диаграммах кооперации.
- •32. Диаграммы взаимодействия с разветвленным потоком управления
- •33. Нефункциональные требования и их отображение на диаграммах прецедентов
- •34. Понятие эктора и отношения между экторами
- •35. Отношения включения и расширения между экторами
- •36. Причины использования прецедентов.
- •37. Прецеденты в прямом и обратном проектировании
- •38. Обзор case-средств для построения диаграмм uml
- •Visio поддерживает множество локальных языков
- •39. Критерии выделения прецедентов
- •40. Понятие шаблона проектирования
- •41. Основные шаблоны grasp
- •Information Expert (Информационный эксперт)
- •Indirection (Посредник)
- •42. Описание шаблонов проектирования GoF
- •43. Классификация шаблонов проектирования GoF
- •44. Структурные шаблоны проектирования
- •56. Понятие рефакторинга программ
- •57. Анти-шаблоны управления разработкой программ
- •Раздувание по (Software bloat): Разрешение последующим версиям системы требовать всё больше и больше ресурсов
- •58. Анти-шаблоны разработки программ
- •59. Анти-шаблоны в объектно-ориентированном программировании
- •60. Анти-шаблоны в программировании
- •61. Методологические анти-шаблоны
- •62. Анти-шаблоны управления конфигурацией
- •63. Примеры организационных анти-шаблонов
- •64. Социальные анти-шаблоны
- •Шаблоны параллельного программирования (Concurrency)
- •Другие типы шаблонов
- •66. Шаблон делегирования
- •Простой пример
- •67. Шаблон функционального дизайна
- •68. Неизменяемый объект (шаблон проектирования)
- •69. Интерфейс (шаблон проектирования)
- •70. Порождающие шаблоны проектирования
- •71. Абстрактная фабрика (шаблон проектирования)
- •72. Строитель (шаблон проектирования)
- •73. Фабричный метод (шаблон проектирования)
- •74. Отложенная инициализация (шаблон проектирования)
- •75. Объектный пул (шаблон проектирования)
- •76. Прототип (шаблон проектирования)
- •77. Получение ресурса есть инициализация (шаблон проектирования)
- •78. Одиночка (шаблон проектирования)
- •79. Структурные шаблоны
- •80. Адаптер (шаблон проектирования)
- •81. Мост (шаблон проектирования)
- •82. Компоновщик (шаблон проектирования)
- •83. Декоратор (шаблон проектирования)
- •84. Фасад (шаблон проектирования)
- •85. Приспособленец (шаблон проектирования)
- •86. Заместитель (шаблон проектирования)
- •87. Поведенческие шаблоны
- •88. Цепочка ответственности (шаблон проектирования)
- •89. Команда (шаблон проектирования)
- •90. Интерпретатор (шаблон проектирования)
- •91. Итератор (шаблон проектирования)
- •92. Посредник (шаблон проектирования)
- •93. Хранитель (шаблон проектирования)
- •94. Наблюдатель (шаблон проектирования)
- •95. Состояние (шаблон проектирования)
- •96. Стратегия (шаблон проектирования)
- •97. Шаблоны параллельного программирования Шаблоны параллельного программирования (Concurrency)
- •Пример реализации Пример c#
- •Следствия
- •98. Модель-представление-контроллер (шаблон проектирования)
- •99. Технология использования шаблонов проектирования
97. Шаблоны параллельного программирования Шаблоны параллельного программирования (Concurrency)
Active Object
Balking
Double checked locking
Double checked locking (блокировка с двойной проверкой) — шаблон проектирования применяющийся в параллельном программировании. Он предназначен для уменьшения накладных расходов, связанных с получением блокировки. Сначала проверяется условие блокировки без какой-либо синхронизации; поток делает попытку получить блокировку только если результат проверки говорит о том, что ни один другой поток не владеет блокировкой.
На некоторых языках и/или на некоторых машинах невозможно безопасно реализовать данный шаблон. Поэтому иногда его называют анти-паттерном.
Обычно он используется для уменьшения накладных расходов при реализации ленивой инициализации в многопоточных программах, например в составе шаблона проектирования Одиночка. При ленивой инициализации переменной, инициализация откладывается до тех пор, пока значение переменной действительно понадобится при вычислениях.
public sealed class Singleton
{
private Singleton()
{
// инициализировать новый экземпляр объекта
}
private static volatile Singleton singletonInstance;
private static readonly Object syncRoot = new Object();
public static Singleton GetInstance()
{
// создан ли объект
if(singletonInstance == null)
{
// нет, не создан
// только один поток может создать его
lock(syncRoot))
{
// проверяем, не создал ли объект другой поток
if(singletonInstance == null)
{
// нет не создал — создаём
singletonInstance = new Singleton();
}
}
}
return singletonInstance;
}
}
Microsoft подтверждает [5], что при использовании ключевого слова volatile, использование паттерна Double checked locking является безопасным.
Guarded suspension
Half-Sync/Half-Async
Leaders/followers
Monitor Object
Reactor
Read write lock
Scheduler
Планировщик (англ. Scheduler) — Шаблон проектирования обеспечивающий механизм реализации политики планирования, но при этом не зависит ни от одной конкретной политики. Управляет порядком, в соответствии с которым потокам предстоит выполнить последовательный код, используя для этого объект, который явным образом задаёт последовательность ожидающих потоков.
Мотивы
Несколько потоков могут потребовать доступа к ресурсу одновременно, и только один поток в какой-то момент времени может осуществить доступ к ресурсу.
Согласуясь с требованиями программы, потоки должны осуществлять доступ к ресурсу в определенном порядке.
Пример реализации Пример c#
using System;
namespace Digital_Patterns.Concurrency.Sheduler
{
class Printer
{
private static Int32 mID = 0;
private Scheduler _scheduler = new Scheduler();
public void Print(JournalEntry journalEntry)
{
Int32 id = ++mID;
try
{
Console.WriteLine(String.Format(@"{0}: enter scheduler", id));
// вызов не выполниться до тех пор, пока объект Scheduler не решит,
// что подошла очередь распечатать этот объект JournalEntry
_scheduler.Enter(journalEntry);
Console.WriteLine(String.Format(@"{0}: start printing", id));
try
{
//TODO Something
journalEntry.Do(id);
}
finally
{
// вызов метода Done говорит Scheduler о том, что объект JournalEntry
// распечатан, и может подойти очередь вывода на печать другого объекта
// JournalEntry
_scheduler.Done();
Console.WriteLine(String.Format(@"{0}: done scheduler", id));
}
}
catch (Exception) {}
}
}
}
using System;
using System.Collections.Generic;
using System.Threading;
namespace Digital_Patterns.Concurrency.Sheduler
{
/// <summary>
/// Экземпляры классов в этой роли управляют обработкой объектов Request <see cref="JournalEntry"/>,
/// выполняемой объектом Processor <see cref="Printer"/>. Чтобы быть независимыми от типов
/// запросов, класс <see cref="Scheduler"/> не должен ничего знать об управляемом им классе Requect.
/// Вместо этого он осущуствляет доступ к объектам Request через реализуемый ими интерфейс <see cref="ISchedulerOrdering"/>
/// </summary>
class Scheduler
{
/// <summary>
/// Объект синхронизации потоков
/// </summary>
private AutoResetEvent _event = new AutoResetEvent(false);
/// <summary>
/// Устанавливается в null, если управляемый объектом Scheduler ресурс не занят.
/// </summary>
private Thread _runningThread;
/// <summary>
/// Потоки и их запросы ожидающие выполнения
/// </summary>
private Dictionary<Thread, ISchedulerOrdering> _waiting = new Dictionary<Thread, ISchedulerOrdering>();
/// <summary>
/// Метод <see cref="Enter"/> вызывается перед тем, как поток начнет использовать уравляемый ресурс.
/// Метод не выполняется до тех пор пока управляемый ресур не освободиться и объект <see cref="Sheduler"/>
/// не примет решение, что подошла очередь выполнения этого запроса
/// </summary>
/// <param name="s"></param>
public void Enter(ISchedulerOrdering s)
{
var thisThread = Thread.CurrentThread;
lock(this)
{
// Определяем не занат ли планировщик
if(_runningThread == null)
{
// Немедленно начинмем выполненин поступившего запроса
_runningThread = thisThread;
return;
}
_waiting.Add(thisThread, s);
}
lock(thisThread)
{
//Блокируем поток до тех пор, пока планировщик не решит сделать его текущим
while(thisThread != _runningThread)
{
_event.WaitOne();
_event.Set(); // даем возможность другим потокам проверить своё состояние
Thread.Sleep(1);
}
_event.Reset();
}
lock (this)
{
_waiting.Remove(thisThread);
}
}
/// <summary>
/// Вызов метода <see cref="Done"/> указывает на то, что текущий поток завершил работу
/// и управляемый ресурс освободился
/// </summary>
public void Done()
{
lock (this)
{
if (_runningThread != Thread.CurrentThread)
throw new ThreadStateException(@"Wrong Thread");
Int32 waitCount = _waiting.Count;
if (waitCount <= 0)
{
_runningThread = null;
}
else if (waitCount == 1)
{
_runningThread = _waiting.First().Key;
_waiting.Remove(_runningThread);
_event.Set();
}
else
{
var next = _waiting.First();
foreach (var wait in _waiting)
{
if(wait.Value.ScheduleBefore(next.Value))
{
next = wait;
}
}
_runningThread = next.Key;
_event.Set();
}
}
}
}
/// <summary>
/// Вспомогательный класс
/// </summary>
static partial class ConvertTo
{
/// <summary>
/// Получить первый элемент коллекции
/// </summary>
/// <param name="collection"></param>
/// <returns></returns>
public static KeyValuePair<Thread, ISchedulerOrdering> First(this Dictionary<Thread, ISchedulerOrdering> collection)
{
foreach (var item in collection)
{
return item;
}
throw new ArgumentException();
}
}
}
using System;
namespace Digital_Patterns.Concurrency.Sheduler
{
/// <summary>
/// Если несколько операций ожидают доступа к ресурсу, класс<see cref="Scheduler"/> использует
/// данный интерфейс для определения порядка выполнения операций.
/// </summary>
interface ISchedulerOrdering
{
Boolean ScheduleBefore(ISchedulerOrdering s);
}
}
using System;
using System.Threading;
namespace Digital_Patterns.Concurrency.Sheduler
{
/// <summary>
/// Примерный код класса <see cref="JournalEntry"/>, который должен быть
/// распечатан классом <see cref="Printer"/>
/// </summary>
class JournalEntry : ISchedulerOrdering
{
private static DateTime mTime = DateTime.Now;
private DateTime _time;
/// <summary>
/// Возвращает время создания этго объекта
/// </summary>
public DateTime Time { get { return _time; } }
private String _msg;
public JournalEntry(String msg)
{
mTime = mTime.AddSeconds(1);
_time = mTime;
_msg = msg;
}
public void Do(Int32 id)
{
Console.WriteLine(String.Format(@"{0}: Start doing : {1} : {2}", id, _time, _msg));
Thread.Sleep(1000);
Console.WriteLine(String.Format(@"{0}: Finish do : {1} : {2}", id, _time, _msg));
}
/// <summary>
/// Возвращает true, если данный запрос должен
/// обрабатываться перед этим запросом.
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public Boolean ScheduleBefore(ISchedulerOrdering s)
{
if(s is JournalEntry)
{
var otherJournalEntry = (JournalEntry) s;
return (this.Time < otherJournalEntry.Time);
}
return false;
}
}
}
using System;
using System.Threading;
namespace Digital_Patterns.Concurrency.Sheduler
{
public class Example01
{
private Printer _printer;
public void Run()
{
Console.WriteLine(@"Press any key for start, and press again for finish");
Console.ReadKey();
_printer = new Printer();
new Thread(Thread1).Start();
new Thread(Thread2).Start();
new Thread(Thread3).Start();
Console.ReadKey();
}
private void Thread1()
{
var msg1 = new JournalEntry(@"Buy toll 5.45 USD");
var msg2 = new JournalEntry(@"Buy candy 1.05 USD");
var msg3 = new JournalEntry(@"Buy chocolate 3.25 USD");
_printer.Print(msg1);
_printer.Print(msg2);
_printer.Print(msg3);
}
private void Thread2()
{
var msg4 = new JournalEntry(@"Buy postcard 2.05 USD");
var msg5 = new JournalEntry(@"Buy gerland 37.78 USD");
_printer.Print(msg4);
_printer.Print(msg5);
}
private void Thread3()
{
var msg6 = new JournalEntry(@"Buy ball 30.06 USD");
var msg7 = new JournalEntry(@"Buy pipe 1.83 USD");
_printer.Print(msg6);
_printer.Print(msg7);
}
}
}
using System;
using Digital_Patterns.Concurrency.Sheduler;
namespace Digital_Patterns
{
class Program
{
static void Main(string[] args)
{
new Example01().Run();
Console.WriteLine(@"Press any key for end");
Console.ReadKey();
}
}
}
Thread pool
Thread-Specific Storage
Single Thread Execution
Однопоточное выполнение (англ. Single Threaded Execution) — известный также под названием англ. Critical Section. Шаблон проектирования препятствующий конкурентному вызову метода, тем самым запрещая параллельное выполнение этого метода.
Мотивы
Класс содержит методы, которые обновляют или задают значения в переменных экземпляра класса или переменных класса.
Метод манипулирует внешними ресурсами, которые поддерживают только одну операцию в какой-то момент времени.
Методы класса могут вызываться параллельно различными потоками.
Не существует временного ограничения, которое требовало бы от метода немедленного выполнения, как только его вызывают.