C#多线程

今天晚上睡不着,翻来覆去,索性就不睡了,起来把C#的多线程学一下。

什么是线程?

线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但是代码区是共享的,不同的线程可以执行相同的函数。

C#中与线程相关的一点东西:Thread类,封装了线程相关的一系列操作;System.Threading,要用到的命名空间

简单线程的创建

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

namespace testing
{
    class Program
    {
        public static void Print()
        {
            Console.WriteLine("新线程");
        }
        static void Main(string[] args)
        {
            Thread mThread = new Thread(new ThreadStart(Print));
            mThread.Name = "子线程";
            mThread.Start();
            Console.WriteLine(mThread.Name);
            Console.ReadKey();
        }
    }
}

实例化Thread的时候需要用到一个ThreadStart类型的委托,也就是新线程的处理函数。

线程处理的几个重要方法:

start(),启动线程
sleep(int),静态方法,暂停当前线程指定时间
abort(),用于终止一个线程
suspend(),挂起线程
resume(),恢复被挂起的线程

(未完待续)

关于Join方法,用来阻塞方法调用时的当前线程,等待指定线程执行完毕,再恢复当前线程的执行。

示例代码:

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

namespace ThreadLearn
{
    class Program
    {
        public static void Print()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(Thread.CurrentThread.Name + " i=" + i);
            }
        }
        static void Main(string[] args)
        {
            Thread.CurrentThread.Name = "主线程";
            Thread newThread = new Thread(new ThreadStart(Print));
            newThread.Name = "新线程";
            for (int j = 0; j < 20; j++)
            {
                if (j == 10)
                {
                    newThread.Start();
                    newThread.Join();
                }
                else
                {
                    Console.WriteLine(Thread.CurrentThread.Name + " j=" + j);
                }
            }
            Console.ReadLine();
            //i.ToString();
        }
    }
}

 Thread.ThreadState属性

此属性代表了线程的不同状态,取值如下:

Aborted:线程已停止;

AbortRequested:线程的Thread.Abort()方法已被调用,但是线程还未停止;

Background:线程在后台执行,与属性Thread.IsBackground有关;后台线程不影响程序的终止

Running:线程正在正常运行;

Stopped:线程已经被停止;

StopRequested:线程正在被要求停止;

Suspended:线程已经被挂起(此状态下,可以通过调用Resume()方法重新运行);

SuspendRequested:线程正在要求被挂起,但是未来得及响应;

Unstarted:未调用Thread.Start()开始线程的运行;

WaitSleepJoin:线程因为调用了Wait(),Sleep()或Join()等方法处于封锁状态;

线程之间的同步

  • 关键字lock

lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。此语句的形式如下:

Object thisLock = new Object();
lock (thisLock)
{
    // Critical code section
}

下面这段代码来自MSDN,演示了多个线程对同一个对象的操作,保持多个线程之间的同步(http://msdn.microsoft.com/zh-cn/library/c5kehkcz(v=VS.80).aspx

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

namespace ThreadLearn
{
    class Account
    {
        private Object thisLock = new Object();
        int balance;
        Random r = new Random();
        public Account(int initial)
        {
            balance = initial;
        }
        int WithDraw(int amount)
        {
            if (balance < 0)
                throw new Exception("负数");
            lock (thisLock)
            {
                //Console.WriteLine(Thread.CurrentThread.Name);
                if (balance > amount)
                {
                    Console.WriteLine("Balance before WithDraw: " + balance+"  "+Thread.CurrentThread.Name);
                    Console.WriteLine("Amount to WithDraw: -" + amount);
                    balance = balance - amount;
                    Console.WriteLine("Balance after WithDraw: " + balance);
                    return amount;
                }
                else
                {
                    return 0;
                }
            }
        }
        public void DoTransaction()
        {
            for (int i = 0; i < 100; i++)
            {
                WithDraw(r.Next(1, 100));
            }
        }
    }
    class Program
    {
        
        static void Main(string[] args)
        {
            Thread[] thread = new Thread[10];
            Account acc = new Account(1000);
            for (int i = 0; i < 10; i++)
            {
                Thread t = new Thread(new ThreadStart(acc.DoTransaction));
                thread[i] = t;
                thread[i].Name = "Thread Number: " + i.ToString();
            }
            for (int i = 0; i < 10; i++)
            {
                thread[i].Start();
            }
            Console.ReadLine();
            //i.ToString();
        }
    }
}
  •  Monitor

与关键字lock类似,Monitor也用于防止多个线程同时执行指定代码段。事实上,lock就是用Monitor来实现的。

例如:

lock(x)
{
    DoSomething();
}
System.Object obj = (System.Object)x;
System.Threading.Monitor.Enter(obj);
try
{
    DoSomething();
}
finally
{
    System.Threading.Monitor.Exit(obj);
}

这两段代码是等价的,lock关键字更加简洁一些。

 

posted @ 2013-01-26 03:36  大器天下  阅读(417)  评论(1编辑  收藏  举报