Synchronisation des threads C# et pool de threads
L'exemple est très simple, préparez 5 threads, chaque thread génère des nombres sur la console en même temps, et puis observez les résultats de sortie.
Description du code :
////Liste de threads
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(); } }
En observant les résultats de l'exécution, nous pouvons voir que les résultats sont les suivants :
Selon le résultat (la sortie des nombres est irrégulière), on peut voir qu'une interférence s'est produite entre les threads. La stratégie consiste à ajouter un membre de synchronisation pour la synchronisation des threads : >Vous pouvez voir que grâce au mot-clé Lock, le verrouillage d'une variable synchronisée multi-thread peut effectivement synchroniser les threads.
/// <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 });
Utilisez le mot-clé moniteur pour la synchronisation, code :
Affichez les résultats et vous constaterez que les fils de discussion ont été synchronisés .
La troisième méthode : Refactorisons maintenant le code, créons une nouvelle classe ThreadManager et y déplaçons toutes les responsabilités de la classe :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
:
, exécutez-le à nouveau et constatez que les threads sont synchronisés. C'est la quatrième solution pour la synchronisation des threads. Elle est très simple à utiliser, mais elle nécessite d'abord que la logique d'exécution soit placée dans une classe. peut garantir que la logique d'exécution dans cette classe est Toutes les méthodes sont thread-safe, ses performances sont donc relativement inefficaces
.Existe-t-il un moyen de synchroniser les fils de discussion ? La réponse est oui, il s’agit du quatrième pool de threads de méthode. Voyons maintenant comment utiliser le pool de threads pour l'implémenter :
Est-ce que cela complète la logique à l'instant ? Oui, nous pouvons voir les résultats après l'exécution, les threads sont synchronisés. Quels autres avantages le multithreading apporte-t-il ?
Le pool de threads réduit le nombre de créations, de démarrages et d'arrêts de threads, améliorant ainsi l'efficacité L'utilisation du pool de threads nous permet de nous concentrer sur les affaires ; logique plutôt qu'une architecture multi-thread (cependant, la gestion manuelle des threads est à privilégier dans certains cas)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(); }
Si vous avez besoin d'un thread de premier plan ou de définir un niveau de priorité, ou d'un pool de threads Le thread in est toujours un fil de discussion en arrière-plan, et sa priorité est la priorité par défaut
Si vous avez besoin d'un fil de discussion avec une identité fixe pour une sortie facile, suspendez-le ou découvrez-le par son nom ;