Execuție cu un singur thread
Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de
versiunea revizuită pe 22 mai 2019; verificările necesită
4 modificări .
Execuție cu un singur thread |
---|
Execuție cu un singur thread |
Descris în Design Patterns |
Nu |
Execuția single-threaded ( ing. Single Threaded Execution sau ing. Critical Section [1] ) este un model de proiectare paralel care previne un apel de metodă competitivă, interzicând astfel execuția paralelă a acestei metode.
Motive
- Clasa conține metode care actualizează sau setează valori în variabilele de instanță de clasă sau variabilele de clasă.
- Metoda manipulează resurse externe care suportă o singură operație la un moment dat.
- Metodele de clasă pot fi apelate în paralel prin diferite fire.
- Nu există nicio limită de timp care să necesite ca o metodă să fie executată imediat de îndată ce este apelată.
Consecințele
- + Oferă siguranță firului
- − Performanța poate fi redusă
- − Posibil interblocare
Exemplu de implementare
Exemplu C#
folosind System ;
folosind System.Threading ;
namespace Digital_Patterns.Concurrency.Single_Thread_Execution
{
/// <summary>
/// Instanțele clasei <see cref="TrafficSensor"/> sunt asociate cu un
/// senzor de trafic, care surprinde trecerea unui anumit loc pe
/ // o bandă de circulație.
/// </summary>
class TrafficSensor
{
private static Int32 mID = 0 ;
privat ITrafficObserver _observator ;
public Boolean IsRun { get ; set ; }
privat Int32_id ; _
/// <summary>
/// Constructor
/// </summary>
/// <param name="observer">Obiect pentru a semnala că
/// senzorul de trafic asociat cu acest obiect ///
detectează o mașină care trece .</param>
public TrafficSensor ( observator ITrafficObserver ) { _id = ++ mID ; _observer = observator ; IsRun = adevărat ; thread nou ( Run ). Start (); }
/// <summary>
/// Logica generală pentru firul acestui obiect
/// </summary>
private void Run ()
{
while ( IsRun )
{
motorSensor ();
}
}
private static Random mRnd = new Random ();
/// <summary>
/// Această metodă apelează metoda de detectare a obiectului când
/// senzorul de trafic asociat cu acesta detectează
/// o mașină care trece
/// </summary>
private void motorSensor ()
{
//TODO Ceva
Fir . Sleep ( mRnd . Next ( 1000 ));
msg = Sistem . _ reflexie . MethodInfo . GetCurrentMethod (). nume ; Consola . WriteLine ( String . Format ( @"{0} {1} +1" , _id , msg ));
detectează ();
}
/// <summary>
/// Această metodă este apelată de metoda <see cref="motorSensor"/>
/// pentru a raporta trecerea unui vehicul
/// observatorului acestui obiect
/// </summary >
private void detect ()
{
_observer . vehiculTrecut ();
}
/// <summary>
/// Clasele trebuie să implementeze această interfață,
/// astfel încât obiectul <see cref="TrafficSensor"/> să le poată informa despre trecerea
/// vehiculelor
/// </summary>
interfață publică ITrafficObserver { / // <summary> /// Apelat când <see cref="TrafficSensor"/> detectează /// un vehicul care trece. /// </summary> void vehiclePassed (); } } }
folosind System ;
namespace Digital_Patterns.Concurrency.Single_Thread_Execution
{
/// <summary>
/// Instanțele clasei <see cref="TrafficSensorController"/> stochează
/// numărul total de vehicule care trec pe lângă senzorii de trafic
/// asociați cu instanță.
/// </summary>
class TrafficSensorController : TrafficSensor . ITrafficObserver
{
private Int32 _vehicleCount = 0 ;
/// <rezumat>
/// Această metodă este apelată atunci când
senzorul /// de mișcare a vehiculului detectează trecerea unui vehicul. Crește
/// contorul mașinii cu unul.
/// </summary>
public void vehiclePassed ()
{
lock ( this )
{
++ _vehicleCount ;
}
}
/// <summary>
/// Resetează contorul mașinii la zero
/// </summary>
/// <returns></returns>
public Int32 GetAndClearCount ()
{
lock ( this )
{
Int32 count = _vehicleCount ;
_vehicleCount = 0 ;
număr de întoarcere ; } } } }
folosind System ;
folosind System.Threading ;
namespace Digital_Patterns.Concurrency.Single_Thread_Execution
{
/// <summary>
/// Instanțele clasei <see cref="TrafficTransmitter"/> sunt responsabile pentru
/// transmiterea unei valori care determină numărul de mașini care trec prin aceasta
/// drum pe minut.
/// </summary>
class TrafficTransmitter
{
private TrafficSensorController _conrtoller ;
Private Thread _myThread ;
public Boolean IsRun { get ; set ; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="conrtoller">De la <see cref="TrafficSensorController"/> acest obiect
/// va primi valoarea contorului număr de vehicule trecute
/ // mașini</param>
public TrafficTransmitter ( TrafficSensorController conrtoller )
{
_conrtoller = conrtoller ;
_myThread = thread nou ( Run ); IsRun = adevărat ; _myThread . Start (); }
/// <summary>
/// Treceți valoarea contorului numărului de mașini trecute
/// în intervalul de timp
/// </summary>
private void Run ()
{
while ( IsRun )
{
Thread . Somn ( 10000 );
Transmit ( _conrtoller . GetAndClearCount ());
}
}
private void Transmite ( număr Int32 ) { //TODO Ceva var msg = System . reflexie . MethodInfo . GetCurrentMethod (). nume ; Consola . WriteLine ( String . Format ( @"{0} {1}" , msg , count )); } } }
folosind System ;
folosind Digital_Patterns.Concurrency.Single_Thread_Execution ;
namespace Digital_Patterns
{
class Program
{
static void Main ( string [] args )
{
var controller = new TrafficSensorController ();
var transmitter = new TrafficTransmitter ( controler );
Consola . WriteLine ( "Apăsați orice tastă pentru a începe și apăsați din nou pentru a termina" );
Consola . ReadKey ();
var senzor1 = new TrafficSensor ( controler );
var senzor2 = new TrafficSensor ( controler );
Consola . ReadKey ();
senzor1 . IsRun = fals ;
senzor2 . IsRun = fals ;
transmițător . IsRun = fals ;
Consola . writeLine ();
}
}
}
Link -uri
- Mark Grand. Modele în Java Volumul 1: Un catalog de modele de design reutilizabile ilustrate cu UML. - Wiley & Sons, 1998. - 480 p. — ISBN 0471258393 . (vezi rezumatul (în engleză) )