线程
定义:Thread t = new Thread(Test); //可以用匿名 lamda
调用:t.Start("ljc6666");方法可以无参或一个参数,如果要传入多个参数,可以传入一个结构体
namespace _17_线程Thread
{internal class Program{static void Test(){Console.WriteLine("1");Thread.Sleep(3000);//子线程等3sConsole.WriteLine("2");}struct Data{public int Value;public int Value2;}static void show(object o){Data op = (Data)o;Console.WriteLine("给我什么打印什么:"+ op.Value + op.Value2.ToString());}delegate void TestDelegate();static void Main(string[] args){//Thread t = new Thread(Test);//t.Start();//Thread.Sleep(1000);//主线程等1s//Console.WriteLine("3");//Thread t = new Thread(() => Console.WriteLine("拉姆达表达式线程,线程id为:"+Thread.CurrentThread.ManagedThreadId));//t.Start();//Thread t = new Thread(delegate ()//{// Console.WriteLine("匿名表达式线程,线程id为:" + Thread.CurrentThread.ManagedThreadId);//});//t.Start();//Console.WriteLine("主线程,线程id为:" + Thread.CurrentThread.ManagedThreadId);Data data = new Data();data.Value = 1;data.Value2 = 2;Thread t = new Thread(show);//t.Start("ljc6666");t.Start(data);}}
}
前后台线程
只有一个前台线程在运行,应用程序的进程就在运行,如果多个前台线程在运行,但是Main
方法结束了,应用程序的进程仍然是运行的,直到所有的前台线程完成其任务为止。
在默认情况下,用Thread类创建的线程是前台线程。线程池中的线程总是后台线程。
在用Thread类创建线程的时候,可以设置IsBackground属性,表示它是一个前台线程还是一
个后台线程
namespace _18_前台后台线程
{internal class Program{static void Test(){Console.WriteLine(Thread.CurrentThread.Name+"线程开启");Thread.Sleep(1000);Console.WriteLine(Thread.CurrentThread.Name+"线程结束");}static void Main(string[] args){Thread thread = new Thread(Test);thread.IsBackground = true; //设置为后台线程//thread.IsBackground = false; //设置为前台线程thread.Start();Console.WriteLine("主线程结束");}}
}
线程优先顺序以及状态
在Thead类中,可以设置Priority属性,以影响线程的基本优先级 ,Priority属性是一个
ThreadPriority枚举定义的一个值。定义的级别有Highest ,AboveNormal,Normal,BelowNormal 和 Lowest。
需要注意的是,并不是优先级高的执行完了才会执行低的;
另外,下面这个程序由于CPU都很充足,不能很好的体现优先级顺序
如果需要等待线程的结束,可以调用Thread对象的Join方法,表示把Thread加入进来,停
止当前线程,并把它设置为WaitSleepJoin状态,直到加入的线程完成为止。
namespace _19_线程优先级和状态
{internal class A{}internal class Program{static void A(){int i = 0;bool flag = true;while (flag){i++;Console.Write("a:"+i+" ");if (i>200000 )flag = false;}}static void B(){int i = 0;bool flag = true;while (flag){i++;Console.Write("b:" + i + " ");if (i > 200000)flag = false;}}static void C(){int i = 0;bool flag = true;while (flag){i++;Console.Write("c:" + i + " ");if (i > 200000)flag = false;}}static void Main(string[] args){Thread a = new Thread(A);Thread b = new Thread(B);Thread c = new Thread(C);a.Priority = ThreadPriority.Highest;b.Priority = ThreadPriority.Lowest;a.Start();b.Start();a.Join();Console.WriteLine("a线程结束");b.Join();Console.WriteLine("b线程结束");}}
}
线程池
线程池中的所有线程都是后台线程 ,如果进程的所有前台线程都结束了,所有的后台线程就会停
止。
不能把入池的线程改为前台线程 。
不能给入池的线程设置优先级或名称。
入池的线程只能用于时间较短的任务。 如果线程要一直运行(如 Word的拼写检查器线程),就应使
用Thread类创建一个线程。
namespace _20_线程池
{internal class Program{static void Download(object s){for (int i = 0; i <3;i++){Console.WriteLine("线程"+Thread.CurrentThread.ManagedThreadId+"正在下载");Thread.Sleep(100);}}static void Main(string[] args){for(int i = 0; i < 10;i++) {ThreadPool.QueueUserWorkItem(Download);}Thread.Sleep(5000);}}
}
任务
任务有两种启动方式,需要注意的是 任务是后台线程
连续任务
如果一个任务t1的执行是依赖于另一个任务t2的,那么就需要在这个任务t2执行完毕后才开
始执行t1。这个时候我们可以使用连续任务。
连续任务除了第一个任务之外方法都要有参数
namespace _21_任务
{internal class Program{static void DownLoad(){Console.WriteLine("正在下载,请等待...");Thread.Sleep(1000);}static void Ok(object a){Console.WriteLine("下载完成");}static void Main(string[] args){//TaskFactory tf = new TaskFactory();//Task T = tf.StartNew(DownLoad);//Task t = new Task(DownLoad);//t.Start();Task t1 = new Task(DownLoad);Task t2 = t1.ContinueWith(Ok);t1.Start();Thread.Sleep(1500);//任务是后台线程}}
}
资源访问冲突问题
当有多个地方同时访问一个资源时,可能会导致资源冲突(例如一个变量被多个地方使用),此时可以用锁的方式防止被多次调用
缺点:运行速度会降低
namespace _22_资源访问冲突问题
{internal class Class1{private object _lock = new object();private int state = 5;public void changestate() {lock (_lock){if (state == 5){state++;Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "状态为:" + state);}state = 5;}}}internal class Program{static void Main(string[] args){Class1 c1 = new Class1();for (int i = 0; i < 100; i++) {Thread thread = new Thread(c1.changestate);thread.Start();}}}
}
死锁问题
有多个锁的时候需要注意锁的先后顺序,下面这个讲的很好
408-多线程的死锁问题_哔哩哔哩_bilibili