线程同步中异常情况的处理

简介:

 本文主要用来说明多线程中异常情况的处理。

      问题出现:使用Lock进行多线程中的同步的时候,如果在Lock块里面出现了异常,那么同步的资源(变量)就没有办法被释放,最终将导致线程死锁。

复制代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading;
 6 
 7 namespace testLockList
 8 {
 9     class Program
10     {
11 
12         const int ThreadMaxNum = 5;//线程的最大数目
13         static void Main(string[] args)
14         {
15             TestList myList = new TestList();
16             for (int i = 0; i < ThreadMaxNum; i++)//同时建立5个进程,调用Add方法,看锁住了List,是否能对List里面的单个元素进行修改
17             {
18                 Thread myth = new Thread(TestList.add);
19                 myth.Name = string.Format("线程{0}", i);
20                 myth.IsBackground = true;
21                 myth.Start();
22             }
23             while (TestList.AddInvokeCount != 5)
24             {
25                 Thread.Sleep(500);
26             }
27 
28         }
29     }
30 
31     public class TestList
32     {
33         static List<tester> myList = new List<tester>();//一个List
34         static Mutex myMutex = new Mutex();          //信号量
35         public static int AddInvokeCount = 0;        //用于记录Add被调用的次数
36         public TestList()
37         {
38             myList.Add(new tester(0, 0));
39         }
40         static public void add()
41         {
42 
43             lock (myList)
44             {
45 
46 
47                 myMutex.WaitOne();  //信号量P操作
48                 int Num = myList.Count + 1;
49                 Thread.Sleep(1000);//保证线程等待
50 
51                 myList.Add(new tester(Num, Num));
52                 Console.WriteLine(Num);
53                 Console.WriteLine("线程{0}:增加", Thread.CurrentThread.Name);
54                 if (AddInvokeCount == 3)     //这里故意引发一个Exception
55                 {
56                     int b = 0;
57                     int a = 1 / b;
58                 }
59                 AddInvokeCount++;
60             }
61 
62         }
63     }
64     /// <summary>
65     /// 这个类只是用于测试
66     /// </summary>
67     public class tester
68     {
69         int a;
70         int b;
71         public tester(int a, int b)
72         {
73             this.a = a;
74             this.b = b;
75         }
76 
77     }
78 }
复制代码

出现的问题截图,如图1所示。

图1 Lock块内出现异常导致进程死锁

解决方法:使用信号量加try_catch_finally处理异常情况

     注:以下代码跟上面的问题代码不同的只是add()函数

复制代码
 1         static public void add()
 2         {
 3 
 4             try
 5             {
 6                 myMutex.WaitOne();  //信号量P操作
 7                 int Num = myList.Count + 1;
 8                 Thread.Sleep(1000);//保证线程等待
 9 
10                 myList.Add(new tester(Num, Num));
11                 Console.WriteLine(Num);
12                 Console.WriteLine("线程{0}:增加", Thread.CurrentThread.Name);
13                 if (AddInvokeCount == 3)     //这里故意引发一个Exception
14                 {
15                     int b = 0;
16                     int a = 1 / b;  
17                 }
18                 AddInvokeCount++;
19 
20             }
21             catch (System.Exception ex)
22             {
23 
24             }
25             finally
26             {
27                 myMutex.ReleaseMutex(); //信号量V操作
28             }
29 }
复制代码

运行效果,见图2:

图2 修复后效果

2013-01-02  00:33:53

本文转自陈哈哈博客园博客,原文链接http://www.cnblogs.com/kissazi2/archive/2013/01/02/2841847.html如需转载请自行联系原作者


kissazi2

相关文章
|
6月前
|
安全 Java 开发者
丢失的8小时去哪里了?SimpleDateFormat线程不安全,多线程初始化异常解决方案
丢失的8小时去哪里了?SimpleDateFormat线程不安全,多线程初始化异常解决方案
95 0
|
1月前
线程CPU异常定位分析
【10月更文挑战第3天】 开发过程中会出现一些CPU异常升高的问题,想要定位到具体的位置就需要一系列的分析,记录一些分析手段。
62 0
|
30天前
|
监控 Java
在实际应用中选择线程异常捕获方法的考量
【10月更文挑战第15天】选择最适合的线程异常捕获方法需要综合考虑多种因素。没有一种方法是绝对最优的,需要根据具体情况进行权衡和选择。在实际应用中,还需要不断地实践和总结经验,以提高异常处理的效果和程序的稳定性。
19 3
|
30天前
|
监控 Java
捕获线程执行异常的多种方法
【10月更文挑战第15天】捕获线程执行异常的方法多种多样,每种方法都有其特点和适用场景。在实际开发中,需要根据具体情况选择合适的方法或结合多种方法来实现全面有效的线程异常捕获。这有助于提高程序的健壮性和稳定性,减少因线程异常带来的潜在风险。
19 1
|
30天前
|
监控 API
Hook 线程与捕获线程执行异常
【10月更文挑战第11天】Hook 线程和捕获线程执行异常是多线程编程中不可或缺的技术。通过深入理解和掌握这些方法,我们可以提高程序的稳定性和可靠性,更好地应对各种异常情况。同时,在实际应用中要注意平衡性能和准确性,制定合理的异常处理策略,以确保程序的正常运行。
29 1
|
2月前
|
消息中间件 前端开发 NoSQL
面试官:线程池遇到未处理的异常会崩溃吗?
面试官:线程池遇到未处理的异常会崩溃吗?
76 3
面试官:线程池遇到未处理的异常会崩溃吗?
|
2月前
|
监控 Java
线程池中线程异常后:销毁还是复用?技术深度剖析
在并发编程中,线程池作为一种高效利用系统资源的工具,被广泛用于处理大量并发任务。然而,当线程池中的线程在执行任务时遇到异常,如何妥善处理这些异常线程成为了一个值得深入探讨的话题。本文将围绕“线程池中线程异常后:销毁还是复用?”这一主题,分享一些实践经验和理论思考。
133 3
|
3月前
|
Java 数据库连接 数据库
当线程中发生异常时的情况分析
【8月更文挑战第22天】
102 4
|
3月前
|
Java
线程池中线程抛了异常,该如何处理?
【8月更文挑战第27天】在Java多线程编程中,线程池(ThreadPool)是一种常用的并发处理工具,它能够有效地管理线程的生命周期,提高资源利用率,并简化并发编程的复杂性。然而,当线程池中的线程在执行任务时抛出异常,如果不妥善处理,这些异常可能会导致程序出现未预料的行为,甚至崩溃。因此,了解并掌握线程池异常处理机制至关重要。
426 0

热门文章

最新文章