C#线程从陌生到熟悉(2)

首先我们来看看线程的状态

线程状态

表1-1 ThreadState定义的枚举常数

成员名称

   

Aborted

线程处于Stopped状态中

AbortRequested

已对线程调用了Thread.Abort方法,但线程尚未收到试图终止它的挂起的System.Threading. ThreadAbortException

Background

线程正作为后台线程执行(相对于前台线程而言)。此状态可以通过设置Thread.IsBackground属性来控制

Running

线程已启动,它未被阻塞,并且没有挂起的ThreadAbortException

Stopped

线程已停止

StopRequested

正在请求线程停止。这仅用于内部

Suspended

线程已挂起

SuspendRequested

正在请求线程挂起

Unstarted

尚未对线程调用Thread.Start方法

WaitSleepJoin

由于调用WaitSleepJoin,线程已被阻止

Thread对象的ThreadState属性提供一个由ThreadState定义的位掩码,它指示线程的当前状态。一个线程至少总是处于ThreadState枚举中定义的一个可能状态,并且可以同时处于多个状态。

注意,只能在一些调试方案中使用线程状态,而不应该在代码中使用线程状态来同步线程活动。

在创建托管线程时,该线程处于Unstarted状态。线程会保持Unstarted状态,直到被操作系统调度到已启动状态。调用Start方法使操作系统知道该线程可启动,但是它并不直接更改线程的状态。一旦线程处于已启动的状态中,就可以执行许多操作来使线程更改状态。表1-2列出了使状态发生更改的操作,以及相应的新状态。

表1-2 使线程状态发生更改的操作及相应的新状态

   

ThreadState

在公共语言运行库中创建线程

Unstarted

线程调用Start

Unstarted

线程开始运行

Running

续表

   

ThreadState

线程调用Sleep

WaitSleepJoin

线程对其他对象调用Wait

WaitSleepJoin

线程对其他线程调用Join

WaitSleepJoin

另一个线程调用Interrupt

Running

另一个线程调用Suspend

SuspendRequested

线程响应Suspend请求

Suspended

另一个线程调用Resume

Running

另一个线程调用Abort

AbortRequested

线程响应Abort请求

Stopped

线程被终止

Stopped

  

Abort方法,调用该方法后,在当前线程中引发一个ThreadAbortException异常,该异常导致线程死亡!线程进入Stopped状态,不能在重启!
请看下面的例子

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread t1 = new Thread(Print);
            // t1.Abort();引发ThreadAbortException异常
            t1.Start();
           // t1.Abort();
            //t1.Join();阻塞调用线程,直到某个线程终止时为止。
            Console.WriteLine("主线程被调用");
            // t1.Start();引发ThreadAbortException异常无法重新启动
           
        }
        static void Print() 
        {
            Thread.Sleep(2000);
            Console.WriteLine("线程被调用!");
        }
    }
}


从这个例子中,我们可以看出,线程处于Unstarted状态时,调用Abort()方法时,将引发异常!
将第二个注释打开,得到如下结果


线程被终止了!把第四个注释打开,又会引发异常!
在这里我要说明下Join()这个方法,将第三个注释打开,会得到如下结果,


Join这个方法的作用是阻塞调用他的线程,换句话说就是调用他的线程处于阻塞状态,直到这个线程执行结束,调用他的线程才继续执行!这里调用他的线程指的是主线程!

Interrupt 该方法打断一个处于WaitSleepJoin状态的线程。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread t1 = new Thread(Print);
            t1.Start();
            Thread.Sleep(500);
            t1.Interrupt();
            Thread.Sleep(500);
            
            
            Console.WriteLine("主线执行结束!");
        }
        static void Print()
        {
           
            try
            {
                Thread t2=new Thread(Print2);
                t2.Start();
                t2.Join();
                
            }
            catch (Exception e)
            {
                Console.WriteLine("捕获到异常:{0}", e.ToString());
            }
            Console.WriteLine("线程1运行!");
        }
        static void Print2() 
        {
            Thread.Sleep(2000);
             Console.WriteLine("线程2运行!");
           
        }
    }

}

 运行结果为

从中可以看出线程1调同线程2的方法时被打断了,以致于线程1直接运行了!这个就是Interrupt得作用!如果将Interrupt这个方法给注释掉,那就会看到线程2运行完了,线程1才继续运行!Interrupt 该方法打断一个处于WaitSleepJoin状态的线程。应该可以理解了吧!

好了,这次就到这里了!

原文地址:https://www.cnblogs.com/enuo/p/2278034.html