• 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关键字更加简洁一些。

  • 相关阅读:
    微信开发之注册公众号(二)
    我开通个人博客了~~~~
    微信开发之启用开发者模式(三)
    float浮动属性
    数组的定义与特点
    块级元素和行内元素
    对于if判断和switch选择的入门理解
    Form表单
    不知名的作业
    自我介绍
  • 原文地址:https://www.cnblogs.com/7ants/p/2877491.html
Copyright © 2020-2023  润新知