线程知识点和思考练习

知识点

线程是程序执行时的一个单独路径,用来执行单一任务。如果一个程序由多个线程组成,则这些线程可以并行执行,同时执行多个任务,从而提高程序运行效率,加快执行速度。
许多网络下载程序(BT、FLashGet、迅雷等)采用多线程的方式,提高网络下载的速度。

默认情况下,C#程序具有一个线程,执行从Main方法开始到其结束之间的代码。Main方法直接或间接执行的每一个命令都由默认线程(或称为主线程)执行,当Main方法返回时,
这个线程也将终止。
辅助线程可以执行耗时的或时间要求紧迫的任务,使其不占用主线程。例如:
1、辅助线程通常在服务器应用程序中,以便不必等待前面的请求完成即可响应传入的请求。
2、辅助线程可用于桌面应用程序中执行“后台”任务,以便使主线程(用于驱动用户界面元素)保持对用户操作的响应。

C#中,需要用命名空间:System.Threading
System.Threading 命名空间包括了多个支持多线程编程的类和接口,其中,Thread类有重要的作用,可以用来创建并控制先吃呢个,设置优先级并获取其状态。
创建线程:  Thread 线程名=new Thread(new ThreadStart(方法名));

一、Thread类部分属性
CurrentThread (为static)获取当前正在运行的线程。
public static Thread CurrentThread { get; }

IsAlive  获取一个值,该值指示当前线程的执行状态。 (如果此线程已启动并且尚未正常终止或中止,则为 true;否则为 false。 )
public bool IsAlive { get; }

IsBackground  获取或设置一个值,该值指示某个线程是否为后台线程。
public bool IsBackground { get; set; }

Name  获取或设置线程的名称。
public string Name { get; set; }

Priority  获取或设置一个值,该值指示线程的调度优先级。
public ThreadPriority Priority { get; set; }
属性值为 ThreadPriority 值之一。默认值为 Normal。
ThreadPriority 枚举 成员名称及说明
AboveNormal 可以将 Thread 安排在具有 Highest 优先级的线程之后,在具有 Normal 优先级的线程之前。 
BelowNormal 可以将 Thread 安排在具有 Normal 优先级的线程之后,在具有 Lowest 优先级的线程之前。 
Highest 可以将 Thread 安排在具有任何其他优先级的线程之前。 
Lowest 可以将 Thread 安排在具有任何其他优先级的线程之后。 
Normal 可以将 Thread 安排在具有 AboveNormal 优先级的线程之后,在具有 BelowNormal 优先级的线程之前。默认情况下,线程具有 Normal 优先级。 

ThreadState  获取一个值,该值包含当前线程的状态。
public ThreadState ThreadState { get; }
(ThreadState 属性比 IsAlive 属性能提供更多的特定信息。属性值 ThreadState 值之一,它指示当前线程的状态。初始值为 Unstarted。
ThreadState 枚举 指定 Thread 的执行状态。
ThreadState成员名称及说明
Aborted 线程处于 Stopped 状态中。 
AbortRequested 已对线程调用了 Thread.Abort 方法,但线程尚未收到试图终止它的挂起的 System.Threading.ThreadAbortException。 
Background 线程正作为后台线程执行(相对于前台线程而言)。此状态可以通过设置 Thread.IsBackground 属性来控制。 
Running 线程已启动,它未被阻塞,并且没有挂起的 ThreadAbortException。 
Stopped 线程已停止。 
StopRequested 正在请求线程停止。这仅用于内部。 
Suspended 线程已挂起。 
SuspendRequested 正在请求线程挂起。 
Unstarted 尚未对线程调用 Thread.Start 方法。 
WaitSleepJoin 由于调用 Wait、Sleep 或 Join,线程已被阻止。

ThreadState 为线程定义了一组所有可能的执行状态。一旦线程被创建,它就至少处于其中一个状态中,直到终止。在公共语言运行库中创建的线程最初处于 Unstarted 状态中,而进入运行库的外部线程则已经处于 Running 状态中。通过调用 Start 可以将 Unstarted 线程转换为 Running 状态。并非所有的 ThreadState 值的组合都是有效的;例如,线程不能同时处于 Aborted 和 Unstarted 状态中。)

二、Thread类的部分方法
Abort
  已重载。 在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。调用此方法通常会终止线程。
Thread.Abort ()  在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。调用此方法通常会终止线程。  public void Abort ()
Thread.Abort (Object)  在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程并提供有关线程终止的异常信息的过程。调用此方法通常会终止线程。
public void Abort (
    Object stateInfo
)
stateInfo 一个对象,它包含应用程序特定的信息(如状态),该信息可供正被中止的线程使用。 通常感觉使用字符串。

Join 已重载。 阻止调用线程,直到某个线程终止时为止。 
Thread.Join ()  在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻止调用线程,直到某个线程终止为止。

Resume  继续已挂起的线程。  (现在此方法已过时,最好不要用了)

Sleep (为static)已重载。 将当前线程阻止指定的毫秒数。 
Thread.Sleep (Int32)  将当前线程挂起指定的时间。 
public static void Sleep (
    int millisecondsTimeout
)
Thread.Sleep (TimeSpan)  将当前线程阻止指定的时间。 
public static void Sleep (
    TimeSpan timeout
)
TimeSpan表示一个时间间隔。

Start 已重载。 使线程被安排进行执行。 
Thread.Start ()  导致操作系统将当前实例的状态更改为 ThreadState.Running。 

Suspend  挂起线程,或者如果线程已挂起,则不起作用。 (现在此方法已过时,最好不要用了)

三、线程的生命周期
1、启动线程
Start  已重载。 使线程被安排进行执行。
2、阻止线程
Tread类的Sleep()方法可以使一个线程立即停止,将当前线程阻止指定的毫秒数。
3、杀死线程
About()方法可永久杀死一个线程。

四、线程同步
由于线程的执行是随机的,造成了输出结果的混乱,同时也带来了资源共享问题。C#提供了线程同步机制来保证多个线程访问一个共享资源(相同的变量或代码区,也称为临界区
)时,线程能按顺序正常执行。
线程同步是指某个线程的执行不被其他线程干扰,只有该线程执行结束后其他线程才可以执行。C#使用关键字lock实现线程的同步。lock关键字确保一个线程位于代码的临界区时
,另一个线程不进入临界区。
lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。
lock 语句以关键字 lock 开头,它有一个作为参数的对象,在该参数的后面还有一个一次只能由一个线程执行的代码块。
public void Function()
{
    System.Object lockThis = new System.Object();
    lock(lockThis)
    {
        // Access thread-sensitive resources.
    }
}

五、线程的优先级一般不要随意去设置

 

思考练习

using System;
using System.Threading;
namespace ThreadName
{
    public class ThreadClass
    {
        public static void ThreadMethod()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("执行的线程为{0}", Thread.CurrentThread.Name);
            }
        }
    }
    public class Program
    {
        static void Main()
        {
            Thread.CurrentThread.Name = "主线程";
            Thread thread1 = new Thread(new ThreadStart(ThreadClass.ThreadMethod));
            thread1.Name = "子线程";
            //thread1.Start();
            ThreadClass.ThreadMethod();
            thread1.Start();
            Console.ReadLine();
        }
    }
}

 

using System;
using System.Threading;
namespace ThreadLockName
{
    public class ThreadLockClass
    {
        public void ThreadMethod()
        {
            lock (this)
            {
                for (int i = 0; i < 5; i++)
                {
                    Console.WriteLine("当前线程为{0}", Thread.CurrentThread.Name);
                }
            }
        }
    }
    public class Program
    {
        static void Main()
        {
            ThreadLockClass tm1 = new ThreadLockClass();
            ThreadLockClass tm2 = new ThreadLockClass();
            Thread.CurrentThread.Name = "主线程";
            ThreadStart ts1 = new ThreadStart(tm2.ThreadMethod);
            Thread thread1 = new Thread(ts1);
            thread1.Name = "子线程";//先定义线程名字,再启动线程,名字才能有效
            thread1.Start();

            tm1.ThreadMethod();
            Console.ReadLine();

        }
    }
}
posted on 2009-09-26 21:24  友闻语上  阅读(237)  评论(0编辑  收藏  举报