C#线程总结

在我们做项目的时候会经常用到线程,但线程也不是万能的,用线程需要注意的东西也很多,自己做了一下总结

这次总结主要说三个部分

1 线程之委托方法

2 给线程传参

3 三种方法控制线程同步

我们先看一下小例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
using System.Threading;
 
namespace ThreadMethod
{
    class Program
    {      
        static void Main(string[] args)
        {
            ThreadStart _ts = new ThreadStart(MyThread);
            Thread _thread1 = new Thread(_ts);           
            _thread1.Start();           
 
            Console.WriteLine("other Metod");
            Console.ReadLine();
        }
        public static void MyThread()
        {                
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(i + " by Thread " + Thread.CurrentThread.ManagedThreadId);                   
            }                               
        }
    }


1 线程之委托方法

 在方法里我们定义了一个 ThreadStart _ts = new ThreadStart(MyThread);

打开msdn 查看发现这是一个委托 ,表示在 Thread 上执行的方法。

[ComVisible( true )]
public  delegate  void  ThreadStart();

那就是说也可以这么写

Thread _thread2 = new  Thread( delegate ()
  {
      for  ( int  i = 0; i < 5; i++)
      {
          Console.WriteLine(i + " by Thread "  + Thread.CurrentThread.ManagedThreadId);
      }
  });
  //或者
  Thread _thread3 = new  Thread(()=>
  {
      for  ( int  i = 0; i < 5; i++)
      {
          Console.WriteLine(i + " by Thread "  + Thread.CurrentThread.ManagedThreadId);
      }
  });
  _thread2.Start();
  _thread3.Start();

2为线程传递参数

Thread类有一个带参数的委托类型的重载形式

[ComVisibleAttribute(false)] 
public delegate void ParameterizedThreadStart (
	Object obj
)

可以传递一个object参数,因为是个委托我们也可以和上面的那么写
class  Program
{      
     static  void  Main( string [] args)
     {
 
         Thread _thread = new  Thread( new  ParameterizedThreadStart(MyParametFun));
         _thread.Start( "aaa" );
 
         Thread _thread2 = new  Thread(x => { Console.WriteLine(x); });
         _thread2.Start( "bbb" );
         Console.WriteLine( "other Metod" );
         Console.ReadLine();
     }
 
 
     public  static  void  MyParametFun( object  f_str)
     {
         Console.WriteLine(f_str);
     }
}

有时个我们有好几个参数只传一个参数据就不能满足了

我们可以直接用委托要多个参数

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
 
using  System.Threading;
 
namespace  ThreadMethod
{
     class  Program
     {      
         static  void  Main( string [] args)
         {
             int  _x = 1;
             string  _str = "abc" ;
             string  _str2 = "aaaaa" ;
             Thread _thread= new  Thread(()=>{
                 Console.WriteLine(_x);
                 Console.WriteLine(_str);
                 Console.WriteLine(_str2);
             });
             _thread.Start();
             Console.WriteLine( "other Metod" );
             Console.ReadLine();
         }      
     }
}

 

也可以自己写一个中间类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
using System.Threading;
 
namespace ThreadMethod
{
    class Program
    {       
        static void Main(string[] args)
        {
            MyMode _myMode = new MyMode(1, "aa", "bb");
 
            Thread _thread = new Thread(_myMode.ConsoFun);
            _thread.Start();
            Console.WriteLine("other Metod");
            Console.ReadLine();
        }       
    }
 
    public class MyMode
    {
        int _x ;
        string _str ;
        string _str2 ;
        public MyMode() { }
 
        public MyMode(int f_x,string f_str1,string f_str2)
        {
            _x = f_x;
            _str = f_str1;
            _str2 = f_str2;
        }
 
        public void  ConsoFun()
        {
            Console.WriteLine(_x);
                Console.WriteLine(_str);
                Console.WriteLine(_str2);
        }
    }
}

3同步控件

三种方法lock 和Monitor 还有MethodImpl都会让线程同步下面我们一个一个的来说

多个线程访问同一个方法时有可能会出现一个线程修改了一个参数别一个线程进入也修改了这个参数就会发生

错误

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
using System.Threading;
 
namespace ThreadMethod
{
    class Program
    {        
        static int sum = 200;
        static void Main(string[] args)
        {
            Thread _t1 = new Thread(ConFun);
            Thread _t2 = new Thread(ConFun);
            _t1.Start();
            _t2.Start();
            Console.WriteLine("other Metod");
            Console.ReadLine();
        }
 
        public static void ConFun()
        {        
            int i = 0;
            while (i <= 10)
            {
                sum -= i;
                Thread.Sleep(10);
                ++i;
            }      
            Console.WriteLine(sum);
        }
    }  
}

结果是

根据机器的配制不同可能结果也不同

在这个方法里我们是想让第一个线程减10结果应该 是145

第二个线程进去后在145基础上再减结果应该是90

现在说三种方法lock 和Monitor 还有MethodImpl 都会让线程同步,只有一个线程执行完后另一个线程才能访问

我们一个一个来说吧

先看一下lock

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
using System.Threading;
using System.Runtime.CompilerServices;
 
namespace ThreadMethod
{
    class Program
    {
        static object obj = new object();
        static int sum = 200;
        static void Main(string[] args)
        {
            Thread _t1 = new Thread(ConFun);
            Thread _t2 = new Thread(ConFun);
            _t1.Start();
            _t2.Start();
            Console.WriteLine("other Metod");
            Console.ReadLine();
        }
         
        public static void ConFun()
        {
            lock (obj)
            {
                int i = 0;
                while (i <= 10)
                {
                    sum -= i;
                    Thread.Sleep(10);
                    ++i;
                }
            }
            Console.WriteLine(sum);
        }
    }  
}

这样结果就对了吧

还有其它的两种形式

用MethodImpl  要加上

using System.Runtime.CompilerServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
using System.Threading;
using System.Runtime.CompilerServices;
 
namespace ThreadMethod
{
    class Program
    {
        static object obj = new object();
        static int sum = 200;
        static void Main(string[] args)
        {
            Thread _t1 = new Thread(ConFun);
            Thread _t2 = new Thread(ConFun);
            _t1.Start();
            _t2.Start();
            Console.WriteLine("other Metod");
            Console.ReadLine();
        }
        [MethodImpl(MethodImplOptions.Synchronized)]
        public static void ConFun()
        {
            
            int i = 0;
            while (i <= 10)
            {
                sum -= i;
                Thread.Sleep(10);
                ++i;
            }
             
            Console.WriteLine(sum);
        }

Monitor 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
using System.Threading;
 
 
namespace ThreadMethod
{
    class Program
    {
        static object obj = new object();
        static int sum = 200;
        static void Main(string[] args)
        {
            Thread _t1 = new Thread(ConFun);
            Thread _t2 = new Thread(ConFun);
            _t1.Start();
            _t2.Start();
            Console.WriteLine("other Metod");
            Console.ReadLine();
        }
         
        public static void ConFun()
        {
            Monitor.Enter(obj);
            int i = 0;
            while (i <= 10)
            {
                sum -= i;
                Thread.Sleep(10);
                ++i;
            }
            Monitor.Exit(obj);
            Console.WriteLine(sum);
        }
    }  
}
结果都是正确的






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值