通过四段代码理解join、wait、sleep、yield的区别
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(); } } } }
浙公网安备 33010602011771号