通过六段代码理解join、wait、sleep、yield、endInvoke、Waitone的区别
using System; using System.Threading; class Join { static int length1 = 5; static int length2 = 6; private static string[] w1 = new string[length1]; private static string[] w2 = new string[length2]; public static void Worker1() { for (int i = 0; i < length1; i++) { w1[i] = "方法1--" + i.ToString(); AddTime(1); Console.WriteLine(w1[i]); } } public static void Worker2() { for (int i = 0; i < length2; i++) { w2[i] = "方法2--" + i.ToString(); AddTime(1); Console.WriteLine(w2[i]); } } //模拟代码执行时间 private static void AddTime(int s) { DateTime d = DateTime.Now; while (d.AddSeconds(s) > DateTime.Now) { } } static void Main(string[] args) { Thread thread1 = new Thread(new ThreadStart(Worker1)); Thread thread2 = new Thread(new ThreadStart(Worker2)); thread2.Start(); thread1.Start(); //阻塞主线程,直到thread1线程终止为止 //这时在thread1没有执行完,后面的代码是无法执行的。 //当然thread2执不执行完是不管的,并且thread1与thread2是同时无序运行的。 thread1.Join(); Console.WriteLine("方法1已全部执行完成!"); for (int i = 0; i < 5; i++) { Console.WriteLine("主线程开始执行--" + i.ToString()); AddTime(2); } } }
using System; using System.Threading; class Join { static int length1 = 5; static int length2 = 6; private static string[] w1 = new string[length1]; private static string[] w2 = new string[length2]; static Thread thread1 = new Thread(new ThreadStart(Worker1)); static Thread thread2 = new Thread(new ThreadStart(Worker2)); public static void Worker1() { for (int i = 0; i < length1; i++) { thread2.Join(); //等待thread2线程执行完毕后再执行thread1线程的代码 w1[i] = "方法1--" + i.ToString(); AddTime(1); Console.WriteLine(w1[i]); } } public static void Worker2() { for (int i = 0; i < length2; i++) { w2[i] = "方法2--" + i.ToString(); AddTime(1); Console.WriteLine(w2[i]); } } //模拟代码执行时间 private static void AddTime(int s) { DateTime d = DateTime.Now; while (d.AddSeconds(s) > DateTime.Now) { } } static void Main(string[] args) { thread2.Start(); thread1.Start(); //阻塞主线程,直到thread1线程终止为止 //这时在thread1没有执行完,后面的代码是无法执行的。 thread1.Join(); Console.WriteLine("方法1已全部执行完成!"); for (int i = 0; i < 5; i++) { Console.WriteLine("主线程开始执行--" + i.ToString()); AddTime(2); } } }
using System; using System.Threading; namespace Sleep_Wait_Pulse { class Program { static readonly object _locker = new object(); static bool _go; static void Main(string[] args) { new Thread(Work).Start();//新线程会被阻塞,因为_go是false Console.WriteLine("Work线程阻塞中,但主线程继续执行..."); Console.ReadLine(); lock (_locker) { _go = true; //通知一个等待队列中的线程,当前锁的状态被改变,(说白了就是有一个线程可以从等待队列中被移入就绪队列) Monitor.Pulse(_locker);//通知等待的队列中的一个线程继续执行,并且这个线程会重新获取锁 } Thread.Sleep(1000);//主线程阻塞一会,等待Work线程执行 } static void Work() { lock (_locker) { while (!_go) Monitor.Wait(_locker);//阻塞当前的线程,并将这个当前线程移动到等待队列中,然后释放当前线程所占用的锁 } Console.WriteLine("Work线程被唤醒了!"); } } }
using System; using System.Threading; public class Yield { public static void Main(String[] args) { Thread thread1 = new Thread(PrintNumbers); Thread thread2 = new Thread(PrintNumbers); thread1.Name = "线程1"; thread2.Name = "线程2"; thread1.Start(); thread2.Start(); // 设置主线程的名称 Thread.CurrentThread.Name = "主线程"; Console.WriteLine(Thread.CurrentThread.Name); PrintNumbers(); } private static void PrintNumbers() { for (int i = 1; i <= 5; i++) { Console.WriteLine(Thread.CurrentThread.Name + ": " + i); // 当 i 是偶数时,当前线程暂停执行 if (i % 2 == 0) { Console.WriteLine(Thread.CurrentThread.Name + " 让出控制权..."); Thread.Yield(); } } } }
using System; using System.Threading; //当使用BeginInvoke异步调用方法时,如果方法未执行完,EndInvoke方法就会一直阻塞,直到被调用的方法执行完毕。 namespace MyThread { class Program { private delegate int NewTaskDelegate(int ms); private static int newTask(int ms) { Console.WriteLine("任务开始"); Thread.Sleep(ms); Random random = new Random(); int n = random.Next(10000); Console.WriteLine("任务完成"); return n; } static void Main(string[] args) { NewTaskDelegate task = newTask; IAsyncResult asyncResult = task.BeginInvoke(10000, null, null); Console.WriteLine("1234567890"); // 可以使用asyncResult.IsCompleted来判断异步调用是否完成,如果没有完成,我们可以在主线程中执行其他任务。 while (!asyncResult.IsCompleted) { Console.Write("*"); Thread.Sleep(1000); } // EndInvoke方法将阻塞主线程10秒,直到异步调用完成,并返回被异步调用方法的结果。 int result = task.EndInvoke(asyncResult); Console.WriteLine(result); } } }
using System; using System.Threading; //当使用BeginInvoke异步调用方法时,如果方法未执行完,EndInvoke方法就会一直阻塞,直到被调用的方法执行完毕。 namespace MyThread { class Program { private delegate int NewTaskDelegate(int ms); private static int newTask(int ms) { Console.WriteLine("任务开始"); Thread.Sleep(ms); Random random = new Random(); int n = random.Next(10000); Console.WriteLine("任务完成"); return n; } static void Main(string[] args) { NewTaskDelegate task = newTask; IAsyncResult asyncResult = task.BeginInvoke(10000, null, null); Console.WriteLine("1234567890"); // 使用AsyncWaitHandle.WaitOne方法等待异步调用完成,并在等待期间输出*。 // 当异步调用完成时,AsyncWaitHandle.WaitOne方法将返回true,主线程将停止输出*并继续执行。 while (!asyncResult.AsyncWaitHandle.WaitOne(1000, false)) { Console.Write("*"); } // EndInvoke方法将阻塞主线程10秒,直到异步调用完成,并返回被异步调用方法的结果。 int result = task.EndInvoke(asyncResult); Console.WriteLine(result); } } }
浙公网安备 33010602011771号