一. Thread多线程
1. 两种使用方式
通过F12查看Thread后,发现有两类构造函数,ParameterizedThreadStart和ThreadStart,其中
ThreadStart:无参无返回值的委托
ParameterizedThreadStart:无返回值,但是有一个object类型参数的委托
下面Thread的使用都是围绕上面这两个构造函数来进行的。
方式一:(当委托是无参数,但赋值的方法又是有参数的,可以使用这种方式转换)
当只有一行的时候,可以省略{},实际上和下面一个道理
{ ThreadStart tStart = () => TestThread("参数1", "参数2"); //ThreadStart tStart2 = () => //{ // TestThread("参数1", "参数2"); //}; Thread thread = new Thread(tStart); thread.Start(); }
方式二:(当委托是有一个object参数的时候, 如果赋值的方法不是只有一个参数,将不适用与该委托)不推荐这种方式,存在拆箱和装箱问题,效率低
1 { 2 ParameterizedThreadStart pStart = t => TestThread2(t.ToString()); 3 //ParameterizedThreadStart pStart2 = (t) => TestThread2(t.ToString()); 4 //ParameterizedThreadStart pStart3 = (t) => 5 //{ 6 // TestThread2(t.ToString()); 7 //}; 8 Thread thread = new Thread(pStart); 9 thread.Start("参数1"); 10 }
2. 利用Join方法进行线程等待
1 { 2 List<Thread> list = new List<Thread>(); 3 for (int i = 0; i < 5; i++) 4 { 5 string name1 = string.Format("ypf1-{0}", i); 6 string name2 = string.Format("ypf2-{0}", i); 7 ThreadStart tStart = () => TestThread(name1, name2); 8 Thread thread = new Thread(tStart); 9 list.Add(thread); 10 thread.Start(); 11 } 12 //线程等待 13 foreach (var item in list) 14 { 15 item.Join(); 16 } 17 }
3. 补充:可以利用IsBackground设置是否为后台线程
二. ThreadPool多线程
1. 使用方式
ThreadPool开启线程唯一的方式就是 ThreadPool.QueueUserWorkItem() ,QueueUserWorkItem的参数为WaitCallback,WaitCallback为有一个object类型参数的无返回值的委托,那么该委托将怎么应对,无参数函数、一个参数的函数、多个参数的函数。
1 //1. 没有参数 2 { 3 WaitCallback wcl = t => TestThread3(); 4 ThreadPool.QueueUserWorkItem(wcl); 5 } 6 //2. 一个参数 7 { 8 WaitCallback wcl = t => TestThread2(t.ToString()); 9 ThreadPool.QueueUserWorkItem(wcl, "测试参数1"); 10 } 11 //3. 两个参数 12 { 13 //因为WaitCallback委托没法结束有两个参数的方法,这里我们采用将方法封装到类中的方式解决 14 MyTest<string, string> model = new MyTest<string, string>("测试参数1", "测试参数2"); 15 WaitCallback wcl = (t) => 16 { 17 model.TestThread(); 18 }; 19 ThreadPool.QueueUserWorkItem(wcl); 20 }
1 public class MyTest<T,M> 2 { 3 public T msg1 { get; set; } 4 public M msg2 { get; set; } 5 public MyTest(T t1,M m1) 6 { 7 this.msg1 = t1; 8 this.msg2 = m1; 9 } 10 public void TestThread() 11 { 12 Console.WriteLine("线程开始:测试参数为:{0}和{1},当前线程的id为:{2}", msg1, msg2, System.Threading.Thread.CurrentThread.ManagedThreadId); 13 long sum = 0; 14 for (int i = 1; i < 999999999; i++) 15 { 16 sum += i; 17 } 18 Console.WriteLine("线程结束:测试参数为:{0}和{1},当前线程的id为:{2}", msg1, msg2, System.Threading.Thread.CurrentThread.ManagedThreadId); 19 } 20 }
2. 多线程等待
1 List<ManualResetEvent> list = new List<ManualResetEvent>(); 2 for (int i = 0; i < 5; i++) 3 { 4 ManualResetEvent mr = new ManualResetEvent(false); 5 WaitCallback wcl = t => 6 { 7 TestThread2(t.ToString()); 8 mr.Set(); //将该线程设置为终止状态 9 }; 10 list.Add(mr); 11 ThreadPool.QueueUserWorkItem(wcl, "测试参数1"); 12 } 13 foreach (var item in list) 14 { 15 item.WaitOne(); 16 }
3. 线程池的基本设置
1 { 2 //1.设置最大和最小线程数 3 ThreadPool.SetMaxThreads(8, 8); 4 ThreadPool.SetMinThreads(4, 4); 5 //2.工作线程和IO线程最大值和最小值的获取(注释掉上面的设置,然后看下面的获取结果) 6 int workerThreads; 7 int ioThreads; 8 { 9 ThreadPool.GetMaxThreads(out workerThreads, out ioThreads); 10 Console.WriteLine(String.Format("Max worker threads: {0}; Max I/O threads: {1}", workerThreads, ioThreads)); 11 } 12 { 13 ThreadPool.GetMinThreads(out workerThreads, out ioThreads); 14 Console.WriteLine(String.Format("Min worker threads: {0}; Min I/O threads: {1}", workerThreads, ioThreads)); 15 } 16 { 17 ThreadPool.GetAvailableThreads(out workerThreads, out ioThreads); 18 Console.WriteLine(String.Format("Available worker threads: {0}; Available I/O threads: {1}", workerThreads, ioThreads)); 19 } 20 }