Enkeltrådad utförande
Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från
versionen som granskades den 22 maj 2019; kontroller kräver
4 redigeringar .
Enkeltrådad exekvering ( eng. Single Threaded Execution eller eng. Critical Section [1] ) är ett parallellt designmönster som förhindrar ett konkurrerande metodanrop, vilket förbjuder parallell exekvering av denna metod.
Motiv
- Klassen innehåller metoder som uppdaterar eller ställer in värden i klassinstansvariabler eller klassvariabler.
- Metoden manipulerar externa resurser som endast stöder en operation åt gången.
- Klassmetoder kan anropas parallellt av olika trådar.
- Det finns ingen tidsgräns som skulle kräva att en metod körs omedelbart så snart den anropas.
Konsekvenser
- + Ger trådsäkerhet
- − Prestanda kan försämras
- − Förregling möjlig
Implementeringsexempel
C# exempel
använder System ;
använder System.Threading ;
namnutrymme Digital_Patterns.Concurrency.Single_Thread_Execution
{
/// <summary>
/// Förekomster av klassen <see cref="TrafficSensor"/> är associerade med en trafik
/// trafiksensor, som fångar förbipasserandet av en viss plats på
/ // ett körfält.
/// </summary>
class TrafficSensor
{
private static Int32 mID = 0 ;
privat ITrafficObserver _observer ;
public Boolean IsRun { get ; set ; }
privat Int32_id ; _
/// <summary>
/// Konstruktör
/// </summary>
/// <param name="observer">Ett objekt för att signalera att
/// trafiksensorn som är kopplad till detta objekt
/ // upptäcker en passerande bil .</param>
public TrafficSensor ( ITrafficObserver observer )
{
_id = ++ mID ;
_observatör = observatör ;
IsRun = sant ;
ny tråd ( Kör ). Start ();
}
/// <summary>
/// Allmän logik för detta objekts tråd
/// </summary>
private void Run ()
{
while ( IsRun )
{
motitorSensor ();
}
}
private static Random mRnd = new Random ();
/// <sammanfattning>
/// Den här metoden anropar objektets detekteringsmetod när
/// trafiksensorn som är associerad med den upptäcker
/// en passerande bil
/// </summary>
private void motitorSensor ()
{
//TODO Something
Tråd . Sömn ( mRnd . Nästa ( 1000 ));
msg = System . _ reflektion . MethodInfo . GetCurrentMethod (). namn ; Konsol . WriteLine ( String . Format ( @"{0} {1} +1" , _id , msg ));
upptäcka ();
}
/// <sammanfattning>
/// Denna metod anropas av metoden <see cref="motitorSensor"/>
/// för att rapportera ett fordons passage
/// till observatören av detta objekt
/// </summary >
privat void detect ()
{
_observer . fordon Godkänd ();
}
/// <summary>
/// Klasser måste implementera detta gränssnitt,
/// så att <see cref="TrafficSensor"/> objektet kan informera dem om passerande
/// fordon
/// </summary>
offentligt gränssnitt ITrafficObserver
{
/ // <sammanfattning>
/// Anropas när <see cref="TrafficSensor"/> upptäcker
/// ett passerande fordon.
/// </summary>
void vehiclePassed ();
}
}
}
använder System ;
namespace Digital_Patterns.Concurrency.Single_Thread_Execution
{
/// <summary>
/// Instanser av klassen <see cref="TrafficSensorController"/> lagrar det aktuella
/// totala antalet fordon som passerar trafiksensorerna
/// som är associerade med exempel.
/// </summary>
class TrafficSensorController : TrafficSensor . ITrafficObserver
{
privat Int32 _vehicleCount = 0 ;
/// <sammanfattning>
/// Denna metod kallas när trafik
/// fordonsrörelsesensor detekterar en bils passage. Den ökar
/// maskinräknaren med ett.
/// </summary>
public void vehiclePassed ()
{
lock ( this )
{
++ _vehicleCount ;
}
}
/// <summary>
/// Nollställer bilräknaren ///
</summary>
/// <returns></returns>
public Int32 GetAndClearCount ()
{
lock ( this )
{
Int32 count = _vehicleCount ;
_vehicleCount = 0 ;
returräkning ; _ } } } }
använder System ;
använder System.Threading ;
namespace Digital_Patterns.Concurrency.Single_Thread_Execution
{
/// <summary>
/// Instanser av klassen <see cref="TrafficTransmitter"/> är ansvariga för att
/// skickar ett värde som bestämmer antalet bilar som passerar denna
/// väg per minut.
/// </summary>
class TrafficTransmitter
{
private TrafficSensorController _conrtoller ;
privat tråd _min tråd ;
public Boolean IsRun { get ; set ; }
/// <summary>
/// Konstruktör
/// </summary>
/// <param name="conrtoller">Från <see cref="TrafficSensorController"/> kommer detta objekt
/// att få räknarvärdet för antal godkända
/ // bilar</param>
public TrafficTransmitter ( TrafficSensorController conrtoller )
{
_conrtoller = conrtoller ;
_myThread = ny tråd ( Kör );
IsRun = sant ;
_min tråd . Start ();
}
/// <summary>
/// Passera värdet på räknaren för antalet passerade maskiner
/// under tidsintervallet
/// </summary>
private void Run ()
{
while ( IsRun )
{
Thread . Sömn ( 10000 );
Transmit ( _conrtoller . GetAndClearCount ());
}
}
privat void Transmit ( Int32 count )
{
//TODO Something
var msg = System . reflektion . MethodInfo . GetCurrentMethod (). namn ;
Konsol . WriteLine ( String . Format ( @"{0} {1}" , msg , count ));
}
}
}
använder System ;
använder Digital_Patterns.Concurrency.Single_Thread_Execution ;
namnutrymme Digital_Patterns
{
class Program
{
static void Main ( sträng [] args )
{
var controller = new TrafficSensorController ();
var transmitter = new TrafficTransmitter ( controller );
Konsol . WriteLine ( @"Tryck på valfri tangent för start, och tryck igen för att avsluta" );
Konsol . ReadKey ();
var sensor1 = new TrafficSensor ( controller );
var sensor2 = new TrafficSensor ( controller );
Konsol . ReadKey ();
sensor1 . IsRun = false ;
sensor2 . IsRun = false ;
sändare . IsRun = false ;
Konsol . writeLine ();
}
}
}
Länkar
- Mark grand. Mönster i Java Volym 1: En katalog över återanvändbara designmönster illustrerade med UML. - Wiley & Sons, 1998. - 480 sid. — ISBN 0471258393 . (se synopsis (engelska) )