Ütemező (tervezési minta)

Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2019. május 28-án felülvizsgált verziótól ; az ellenőrzések 4 szerkesztést igényelnek .
Ütemező
Ütemező
Leírása: Tervezési minták Nem

Az ütemező egy párhuzamos tervezési minta , amely  mechanizmust biztosít egy ütemezési házirend megvalósításához, de nem függ semmilyen konkrét házirendtől. Azt a sorrendet szabályozza, amelyben a szálak szekvenciális kódot hajtsanak végre egy olyan objektum használatával, amely kifejezetten meghatározza a várakozó szálak sorrendjét.

Motívumok

Megvalósítási példa

C# példa

a rendszer használatával ; névtér Digital_Patterns.Concurrency.Sheduler { class Printer { private static Int32 mID = 0 ; private Scheduler _scheduler = new Scheduler (); public void Nyomtatás ( JournalEntry journalEntry ) { Int32 id = ++ mID ; próbálkozzon { Console . WriteLine ( String . Formátum ( @"{0}: írja be az ütemezőt" , id )); // a hívás addig nem kerül végrehajtásra, amíg az Ütemező objektum // úgy dönt, hogy ideje kinyomtatni ezt a JournalEntry _scheduler objektumot . Enter ( JournalEntry ); Konzol . WriteLine ( String . Formátum ( @"{0}: nyomtatás indítása" , id )); próbálkozzon { //TODO Something journalEntry . Do ( id ); } végül { // a Done metódus meghívása közli az ütemezővel, hogy // a JournalEntry objektum ki lett nyomtatva, és egy másik // JournalEntry _scheduler objektum lehet a print mellett . Kész (); Konzol . WriteLine ( String . Formátum ( @"{0}: kész ütemező" , id )); } } fogás ( Kivétel ) {} } } }


a rendszer használatával ; a System.Collections.Generic használatával ; a System.Threading használatával ; névtér Digital_Patterns.Concurrency.Sheduler { /// <summary> /// Ebben a szerepkörben az osztálypéldányok szabályozzák a Request objektumok feldolgozását <lásd cref="JournalEntry"/> /// a Processor objektum által végrehajtott <lásd cref="Nyomtató" "/> . Ahhoz, hogy a /// kéréstípusoktól független legyen , a <see cref="Scheduler"/> osztálynak semmit sem kell tudnia az általa kezelt Request osztályról. /// Ehelyett az általuk megvalósított felületen keresztül éri el a Request objektumokat <see cref="ISchedulerOrdering"/> /// </summary> class Scheduler { /// <summary> /// Szálszinkronizációs objektum /// < / összegzés> private AutoResetEvent _event = new AutoResetEvent ( false ); /// <összegzés> /// Állítsa nullára, ha az ütemező által kezelt erőforrás tétlen. /// </summary> private Thread _runningThread ; /// <summary> /// Szálak és kéréseik várakoznak /// </summary> private Dictionary < Thread , ISchedulerOrdering > _waiting = new Dictionary < Thread , ISchedulerOrdering >(); /// <summary> /// A <see cref="Enter"/> metódus meghívásra kerül, mielőtt a szál elkezdené használni a felügyelt erőforrást. /// A metódus addig nem hajtódik végre, amíg a felügyelt erőforrás fel nem szabadul, és a <see cref="Sheduler"/> objektum /// úgy dönt, hogy a kérés végrehajtási sora megérkezett /// </summary> /// <param name ="s"></param> public void Enter ( ISchedulerOrdering s ) { var thisThread = Szál . CurrentThread ; lock ( this ) { // Határozza meg, hogy az ütemező foglalt- e if ( _runningThread == null ) { // Azonnal kezdje el végrehajtani a bejövő kérést _runningThread = thisThread ; visszatérés ; } _vár . Add ( thisThread , s ); } lock ( thisThread ) { // Blokkolja a szálat mindaddig, amíg az ütemező úgy dönt, hogy az aktuális szál lesz , miközben ( thisThread != _runningThread ) { _event . várakozó (); _esemény . set (); // hagyja, hogy a többi szál ellenőrizze állapotát Thread . alvás ( 1 ); } _esemény . visszaállítás (); } zár ( ez ) { _vár . Eltávolítás ( thisThread ); } } /// <summary> /// A <see cref="Done"/> metódus meghívása azt jelzi, hogy az aktuális szál leállt /// és a felügyelt erőforrás felszabadult /// </summary> public void Kész () { lock ( this ) { if ( _runningThread != Thread . CurrentThread ) throw new ThreadStateException ( @"Wrong Thread" ); Int32 waitCount = _waiting . gróf ; if ( várniSzám <= 0 ) { _futószál = null ; } else if ( waitCount == 1 ) { _runningThread = _waiting . először (). kulcs ; _vár . Eltávolítás ( _runningThread ); _esemény . set (); } else { var next = _vár . első (); foreach ( var wait in _waiting ) { if ( várjon . Érték . Ütemezés előtt ( next . Value )) { next = vár ; } } _runningThread = következő . kulcs ; _esemény . set (); } } } } /// <summary> /// Segítő osztály /// </summary> statikus részleges osztály ConvertTo { /// <summary> /// A gyűjtemény első elemének lekérése /// </summary> /// < param name= "collection"></param> /// <returns></returns> public static KeyValuePair < ​​Thread , ISchedulerOrdering > Először ( ez a szótár < Thread , ISchedulerOrdering > collection ) { foreach ( var item in collection ) { cikk visszaküldése ; } dob új ArgumentException (); } } }


a rendszer használatával ; névtér Digital_Patterns.Concurrency.Sheduler { /// <summary> /// Ha több művelet vár egy erőforrás elérésére, a <see cref="Scheduler"/> osztály /// ezt a felületet használja annak meghatározására, hogy milyen sorrendben műveleteket kell végrehajtani. /// </summary> interface ISchedulerOrdering { Boolean ScheduleBefore ( ISchedulerOrdering s ); } }


a rendszer használatával ; a System.Threading használatával ; névtér Digital_Patterns.Concurrency.Sheduler { /// <summary> /// Minta <lásd a cref="JournalEntry"/> osztálykódot, amelyet /// ki kell nyomtatnia <see cref="Printer"/> /// < /summary > class JournalEntry : ISchedulerOrdering { private static DateTime mTime = DateTime . most ; privát DateTime _time ; /// <summary> /// Az objektum létrehozási idejét adja vissza /// </summary> public DateTime Time { get { return _time ; } } privát karakterlánc_üzenet ; _ public JournalEntry ( String msg ) { mTime = mTime . AddSeconds ( 1 ); _time = mTime ; _msg = msg ; } public void Do ( Int32 id ) { Konzol . WriteLine ( String . Formátum ( @"{0}: Kezdje el : {1} : {2}" , id , _time , _msg )); szál . Alvás ( 1000 ); Konzol . WriteLine ( String . Formátum ( @"{0}: Befejezés do : {1} : {2}" , id , _time , _msg )); } /// <összefoglaló> /// Igaz értéket ad vissza, ha ezt a kérést /// a kérés előtt kell feldolgozni. /// </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 ; } } }


a rendszer használatával ; a System.Threading használatával ; névtér Digital_Patterns.Concurrency.Sheduler { public class Példa01 { private Printer _printer ; public void Futtatás () { Konzol . WriteLine ( @"Nyomja meg bármelyik gombot az indításhoz, és nyomja meg újra a befejezéshez" ); Konzol . ReadKey (); _printer = új nyomtató (); új szál ( Thread1 ). Indítás (); új szál ( Thread2 ). Indítás (); új szál ( Thread3 ). Indítás (); Konzol . ReadKey (); } private void Thread1 () { var msg1 = new JournalEntry ( @"Újdíj vásárlása 5,45 USD" ); var msg2 = new JournalEntry ( @"cukorka vásárlása 1,05 USD" ); var msg3 = new JournalEntry ( @"Vegyél csokoládét 3,25 USD-ért" ); _printer . Nyomtatás ( msg1 ); _printer . Nyomtatás ( msg2 ); _printer . Nyomtatás ( msg3 ); } private void Thread2 () { var msg4 = new JournalEntry ( @"Levelezőlap vásárlása 2,05 USD" ); var msg5 = new JournalEntry ( @"Buy Gerland 37.78 USD" ); _printer . Nyomtatás ( msg4 ); _printer . Nyomtatás ( msg5 ); } private void Thread3 () { var msg6 = new JournalEntry ( @"Gyó vásárlás 30,06 USD" ); var msg7 = new JournalEntry ( @"Buy pipe 1,83 USD" ); _printer . Nyomtatás ( msg6 ); _printer . Nyomtatás ( msg7 ); } } }


a rendszer használatával ; a Digital_Patterns.Concurrency.Sheduler használatával ; névtér Digital_Patterns { class Program { static void Main ( string [] args ) { new Példa01 (). futni (); Konzol . WriteLine ( @"Nyomja meg bármelyik billentyűt a befejezéshez" ); Konzol . ReadKey (); } } }

Linkek

  • Mark grand. Minták a Java-ban 1. kötet: UML-lel illusztrált, újrafelhasználható tervezési minták katalógusa. - Wiley & Sons, 1998. - 480 p. — ISBN 0471258393 . (lásd az összefoglalót  (angol) )