c#之线程总结(一)

简介: 在我们做项目的时候会经常用到线程,但线程也不是万能的,用线程需要注意的东西也很多,自己做了一下总结 这次总结主要说三个部分 1 线程之委托方法 2 给线程传参 3 三种方法控制线程同步 我们先看一下小例子: using System; using System.

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

这次总结主要说三个部分

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

现在说三种方法lockMonitor 还有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);
        }
    }  
}

  

结果都是正确的

 

 

 

目录
相关文章
|
2月前
|
存储 安全 Java
C++线程浅谈
C++线程浅谈
|
7月前
|
Java C语言 Python
线程那些事
线程那些事
29 0
|
7月前
|
算法 安全 程序员
线程小练习
线程小练习
|
9月前
|
算法 Java
线程通过管道通信
线程通过管道通信
|
10月前
|
Java Linux 调度
03.关于线程你必须知道的8个问题(中)
大家好,我是王有志,欢迎来到《Java面试都问啥?》。我们书接上回,继续聊Java面试中关于线程的问题。
57 1
03.关于线程你必须知道的8个问题(中)
|
10月前
|
Java Linux 程序员
04.关于线程你必须知道的8个问题(下)
大家好,我是王有志。今天是Java面试中线程问题的最后一部分内容,包括我们来聊同步与互斥,线程的本质,调度,死锁以及线程的优缺点等问题。
91 1
04.关于线程你必须知道的8个问题(下)
|
10月前
|
算法 NoSQL Java
02.关于线程你必须知道的8个问题(上)
大家好,我是王有志,欢迎来到《Java面试都问啥?》。 今天我们来一起看看在面试中,关于线程各大公司大都喜欢问哪些问题。
81 1
02.关于线程你必须知道的8个问题(上)
|
缓存 监控 Java
线程
多线程
91 0
|
Java 编译器 Linux
初识 线程
初识 线程
86 0
初识 线程
|
C++
C++ | C++线程
c++创建线程的方式不止一种。
97 0