C#-Thread-Synchronisierung und Thread-Pool
Das Beispiel ist sehr einfach, bereiten Sie 5 Threads vor, jeder Thread gibt gleichzeitig Zahlen an die Konsole aus und Beobachten Sie dann die Ausgabeergebnisse.
Codebeschreibung:
////Thread-Liste
private static List<Thread> _threadList; static voidMain(string[] args) { Program._threadList= new List<Thread>(); ////附加5个线程 for (inti = 0; i < 5; i++) { Program.AppendThread(); } ////开始执行所有测试线程 Program.ExecuteThread(); ////按任意键退出 Console.ReadLine(); } /// <summary> /// 将新的测试线程附加到测试线程列表,线程执行逻辑就是输出10个数字 /// 注意初始化的时候设置为后台线程了,这样可以保证主线程退出的时候其他线/// 程自动退出 /// </summary> public staticvoid AppendThread() { Program._threadList.Add(newThread(new ThreadStart( () => { for (int i = 0; i < 10; i++) { Console.WriteLine(i); } })){ IsBackground = true }); } /// <summary> /// 开始执行所有测试线程 /// </summary> public staticvoid ExecuteThread() { foreach(Thread t in _threadList) { t.Start(); } }
Wenn wir die Ausführungsergebnisse betrachten, können wir sehen, dass die Ergebnisse wie folgt sind:
Anhand des Ergebnisses (die Ausgabe der Zahlen ist unregelmäßig) ist ersichtlich, dass es zu Interferenzen zwischen Threads gekommen ist. Die Strategie besteht darin, ein Synchronisierungsmitglied für die Thread-Synchronisierung hinzuzufügen: >Sie können sehen, dass das Sperren einer synchronisierten Multithread-Variable durch das Lock-Schlüsselwort tatsächlich Threads synchronisieren kann.
/// <summary> /// 多线程同步的对象 /// </summary> private static object _syncObj = new object(); 另外,在线程执行的地方加锁: Program._threadList.Add(newThread(new ThreadStart( () => { lock (_syncObj) { for (int i = 0; i < 10;i++) { Console.WriteLine(i); } } })) { IsBackground = true });
Verwenden Sie das Monitor-Schlüsselwort für die Synchronisierung, Code:
Sehen Sie sich die Ergebnisse an und Sie werden feststellen, dass die Threads synchronisiert wurden .
Dritter Weg: Lassen Sie uns nun den Code umgestalten, eine neue ThreadManager-Klasse erstellen und alle Verantwortlichkeiten der Klasse hinein verschieben:Monitor.Enter(_syncObj); try { for (int i = 0; i < 10; i++) { Console.WriteLine(i); } } finally { Monitor.Exit(_syncObj); }
class ThreadManager { /// <summary> /// 线程列表 /// </summary> private staticList<Thread> _threadList; staticThreadManager() { _threadList = new List<Thread>(); } /// <summary> /// 附加新线程 /// </summary> public staticvoid AppendThread() { ThreadManager._threadList.Add(newThread(new ThreadStart( () => { for (int i = 0; i < 10; i++) { Console.WriteLine(i); } })){ IsBackground = true }); } /// <summary> /// 开始执行所有线程 /// </summary> public staticvoid ExecuteThread() { foreach(Thread t in _threadList) { t.Start(); } } }
static voidMain(string[] args) { ////附加5个线程 for (int i = 0; i < 5; i++) { ThreadManager.AppendThread(); } ////开始测试 ThreadManager.ExecuteThread(); ////按任意键继续 Console.ReadLine(); }
ThreadManager
hinzu:
, führen Sie es erneut aus und stellen Sie fest, dass die Threads synchronisiert sind. Sie ist sehr einfach zu verwenden, erfordert jedoch zunächst die Platzierung der Ausführungslogik in einer Klasse Stellen Sie sicher, dass die Ausführungslogik in dieser Klasse ist. Alle Methoden sind threadsicher, sodass ihre Leistung relativ ineffizient ist
.Gibt es eine Möglichkeit, Threads zu synchronisieren? Die Antwort lautet: Ja, das ist der vierte Methoden-Thread-Pool. Schauen wir uns nun an, wie der Thread-Pool zur Implementierung verwendet wird:
Vervollständigt dies gerade die Logik? Ja, wir können die Ergebnisse nach dem Ausführen sehen, die Threads sind synchronisiert. Welche weiteren Vorteile bringt Multithreading?
Der Thread-Pool reduziert die Anzahl der Thread-Erstellung, -Starts und -Stopps und verbessert dadurch die Effizienz. Durch die Verwendung des Thread-Pools können wir uns auf das Geschäft konzentrieren Logik statt Multithread-Architektur (in einigen Fällen sollte jedoch die manuelle Thread-Verwaltung bevorzugt werden)static void Main(string[]args) { /////定义一个waitCallback对象,并定义它的行为,就是向控制台输出十个数字同时可以传递/////一个参数(这个参数是可选的) WaitCallback work = new WaitCallback((o)=> { for(int i = 0; i < 10; i++) { Console.WriteLine(i); } }); ////执行5次 for (inti = 0; i < 5; i++) { /////如果这里需要传递参数,可以调用另一个重载方法 ThreadPool.QueueUserWorkItem(work); } ////按任意键继续 Console.ReadLine(); }
Wenn Sie einen Vordergrund-Thread benötigen oder eine Prioritätsstufe oder einen Thread-Pool festlegen Der Thread in ist immer ein Hintergrundthread und seine Priorität ist die Standardeinstellung.
Wenn Sie einen Thread mit einer festen Identität zum einfachen Beenden benötigen, halten Sie ihn an oder ermitteln Sie ihn anhand des Namens.