通过四段代码理解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);
        }
    }
}
View Code
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);
        }
    }
}
View Code
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线程被唤醒了!");
        }
    }
}
View Code
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();
            }
        }
    }
}
View Code

 

posted on 2026-03-09 16:22  喝咖啡就蒜瓣儿  阅读(0)  评论(0)    收藏  举报

导航