三颗纽扣

世界上最宽广的是海洋,比海洋更宽广的是天空,比天空更宽广的是人的胸怀

导航

try-cache-finally 在线程被杀掉时还有作用吗?

问题起因是因为在线程中申请了读写锁,如果一个线程被杀掉没有机会释放锁,那么杀掉线程就是一个很危险的操作,可能导致其他线程申请锁时被死锁。因此实验了一下。结论是即使线程被杀,try-cache-finally 依然有效,因为实际上抛出了线程终止异常ThreadAbortException,不多废话,看结果。

        [TestFixture]
        private class Test
        {
            ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();

            class Locker : IDisposable
            {
                ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
                public Locker(ReaderWriterLockSlim lockSlim)
                {
                    _lock = lockSlim;
                    _lock.EnterReadLock();
                }
                public void Dispose()
                {
                    if (_lock == null) return;
                    var locker = _lock;
                    _lock = null;
                    locker.ExitReadLock();
                    Console.WriteLine("thread3 released");
                }
            }

            [Test]
            public void TestMethod()
            {
                var t1 = new Thread(Thread1){Name = "thread1"};
                var t2 = new Thread(Thread2) { Name = "thread2" };
                var t3 = new Thread(Thread3) { Name = "thread3" };
                t1.Start();
                t2.Start();
                t3.Start();
                Thread.Sleep(300);

                t2.Abort();
                t3.Abort();
                Thread.Sleep(1000);
                t1.Abort();

                t1.Join();
                t2.Join();
                t3.Join();
            }

            public void Thread1()
            {
                Thread.Sleep(1000);
                _lock.EnterWriteLock();
                Console.WriteLine("thread1 locked");
                Thread.Sleep(5000);
                _lock.ExitWriteLock();
                Console.WriteLine("thread1 released");
            }

            public void Thread2()
            {
                _lock.EnterReadLock();
                Console.WriteLine("thread2 locked");
                try
                {
                    while (true)
                    {
                        // NOP
                    }
                }
                finally
                {                    
                    _lock.ExitReadLock();
                    Console.WriteLine("thread2 released");
                }
            }

            public void Thread3()
            {
                using (new Locker(_lock))
                {
                    Console.WriteLine("thread3 locked");
                    while (true)
                    {
                        // NOP
                    }
                }
            }

        }

 输出结果:

thread2 locked
thread3 locked
---- UNHANDLED EXCEPTION ----
Thread Name: thread2
System.Threading.ThreadAbortException: 正在中止线程。
   在 Wellcomm.Dts.Xmq.XmqQueue.Test.Thread2() 位置 D:\shwen\DotNetProjects\Wellcomm.Dts\Wellcomm.Dts.Xmq\XmqQueue.cs:行号 636
   在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   在 System.Threading.ExecutionContext.runTryCode(Object userData)
   在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   在 System.Threading.ThreadHelper.ThreadStart()
thread2 released
---- UNHANDLED EXCEPTION ----
Thread Name: thread3
System.Threading.ThreadAbortException: 正在中止线程。
   在 Wellcomm.Dts.Xmq.XmqQueue.Test.Thread3() 位置 D:\shwen\DotNetProjects\Wellcomm.Dts\Wellcomm.Dts.Xmq\XmqQueue.cs:行号 653
   在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   在 System.Threading.ExecutionContext.runTryCode(Object userData)
   在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   在 System.Threading.ThreadHelper.ThreadStart()
thread3 released
thread1 locked
---- UNHANDLED EXCEPTION ----
Thread Name: thread1
System.Threading.ThreadAbortException: 正在中止线程。
   在 System.Threading.Thread.SleepInternal(Int32 millisecondsTimeout)
   在 System.Threading.Thread.Sleep(Int32 millisecondsTimeout)
   在 Wellcomm.Dts.Xmq.XmqQueue.Test.Thread1() 位置 D:\shwen\DotNetProjects\Wellcomm.Dts\Wellcomm.Dts.Xmq\XmqQueue.cs:行号 625
   在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   在 System.Threading.ExecutionContext.runTryCode(Object userData)
   在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   在 System.Threading.ThreadHelper.ThreadStart()

posted on 2012-10-28 13:09  三颗纽扣  阅读(779)  评论(0编辑  收藏  举报