C#线程基础
暂停线程:
static void Main(string[] args) { Thread thread = new Thread(Common.PrintNumbersWithDelay); thread.Start(); Common.PrintNumbers(); Console.ReadKey(); }
等待线程:
Thread thread = new Thread(Common.PrintNumbersWithDelay); thread.Start(); // 等待线程 thread.Join(); Console.WriteLine("打印完成!"); Console.ReadKey();
终止线程:
static void Main(string[] args) { Console.WriteLine("主线程开始..."); //创建一个子线程并启动 Thread t = new Thread(Common.PrintNumbersWithDelay); t.Start(); // 主线程暂停6秒 Thread.Sleep(TimeSpan.FromSeconds(6)); // 终止子线程t t.Abort(); Console.WriteLine("子线程终止了..."); Thread t1 = new Thread(Common.PrintNumbers); t1.Start(); Common.PrintNumbers(); Console.ReadKey(); }
检测线程状态:
static void Main(string[] args) { Thread t1 = new Thread(Common.PrintNumbersWithStatus); t1.Name = "t1"; Thread t2 = new Thread(DoNothing); t2.Name = "t2"; Console.WriteLine($"线程{t1.Name}的状态是:{t1.ThreadState.ToString()}"); Console.WriteLine($"线程{t2.Name}的状态是:{t2.ThreadState.ToString()}"); t1.Start(); t2.Start(); for (int i = 0; i < 30; i++) { Console.WriteLine($"线程{t1.Name}的状态是:{t1.ThreadState.ToString()}"); } Thread.Sleep(TimeSpan.FromSeconds(4)); t1.Abort(); Console.WriteLine($"线程{t1.Name}的状态是:{t1.ThreadState.ToString()}"); Console.WriteLine($"线程{t2.Name}的状态是:{t2.ThreadState.ToString()}"); Console.ReadKey(); } static void DoNothing() { Thread.Sleep(TimeSpan.FromSeconds(2)); }
线程优先级:
class Program { static void Main(string[] args) { Console.WriteLine($"主线程{Thread.CurrentThread.Name}的优先级是{Thread.CurrentThread.Priority}"); Console.WriteLine("在所有CPU内核上运行线程"); RunThreads(); Thread.Sleep(TimeSpan.FromSeconds(3)); Console.WriteLine("在一个CPU内核上运行线程"); Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(1); RunThreads(); Console.ReadKey(); } static void RunThreads() { ThreadSample sample = new ThreadSample(); Thread t1 = new Thread(sample.CountNumbers); t1.Name = "t1"; Thread t2 = new Thread(sample.CountNumbers); t2.Name = "t2"; t1.Priority = ThreadPriority.Highest; t2.Priority = ThreadPriority.Lowest; t1.Start(); t2.Start(); Thread.Sleep(TimeSpan.FromSeconds(2)); sample.Stop(); } } class ThreadSample { private bool _isStopped = false; public void Stop() { _isStopped = true; } public void CountNumbers() { long count = 0; while(!_isStopped) { count++; } Console.WriteLine($"线程{Thread.CurrentThread.Name}的优先级是{Thread.CurrentThread.Priority},计数器的值为{count}"); } }
前后台线程:
class Program { static void Main(string[] args) { var sampleForeground = new ThreadSample(10); var sampleBackground = new ThreadSample(20); // 区别:进程会等待所有的前台线程完成后再结束工作,但是如果最后只剩下后台线程,则会直接结束工作 var t1 = new Thread(sampleForeground.CountNumbers); t1.Name = "前台线程"; var t2 = new Thread(sampleBackground.CountNumbers); t2.Name = "后台线程"; t2.IsBackground = true; t1.Start(); t2.Start(); } } class ThreadSample { private readonly int _count; public ThreadSample(int count) { _count = count; } public void CountNumbers() { for (int i = 0; i < _count; i++) { Thread.Sleep(TimeSpan.FromSeconds(0.5)); Console.WriteLine($"{Thread.CurrentThread.Name} 输出 {i}"); } } }
线程传递参数:
class Program { static void Main(string[] args) { var sample = new ThreadSample(10); var t1 = new Thread(sample.CountNumbers); t1.Name = "t1"; t1.Start(); t1.Join(); Console.WriteLine("==================================="); var t2 = new Thread(Count); t2.Name = "t2"; t2.Start(8); t2.Join(); Console.WriteLine("==================================="); // 使用lambda表达式引用另一个C#对象的方式被称为闭包 var t3 = new Thread(() => { CountNumbers(9); }); t3.Name = "t3"; t3.Start(); t3.Join(); Console.WriteLine("==================================="); // 在lambda表达式中使用任何局部变量时,C#会生成一个类,并将该变量作为该类的一个属性 // 共享该变量值 int i = 10; var t4 = new Thread(() => { PrintNumbers(i); }); t4.Name = "t4"; i = 12; var t5 = new Thread(() => { PrintNumbers(i); }); t5.Name = "t4"; t4.Start(); t5.Start(); Console.ReadKey(); } static void CountNumbers(int count) { for (int i = 0; i < count; i++) { Thread.Sleep(TimeSpan.FromSeconds(0.5)); Console.WriteLine($"线程{Thread.CurrentThread.Name}输出{i}"); } } static void Count(object obj) { CountNumbers((int)obj); } static void PrintNumbers(int number) { Console.WriteLine($"线程{Thread.CurrentThread.Name}输出{number}"); } } class ThreadSample { private readonly int _count; public ThreadSample(int count) { _count = count; } public void CountNumbers() { for (int i = 0; i < _count; i++) { Thread.Sleep(TimeSpan.FromSeconds(0.5)); Console.WriteLine($"{Thread.CurrentThread.Name} 输出 {i}"); } } }
Lock:
public abstract class CounterBase { public abstract void Increase(); public abstract void Decrease(); }
public class CounterNoLock : CounterBase { public int Count { get; private set; } public override void Decrease() { Count--; } public override void Increase() { Count++; } }
public class CounterWithLock : CounterBase { public int Count { get; private set; } private readonly object _syncObj = new object(); public override void Decrease() { lock(_syncObj) { Count--; } } public override void Increase() { lock (_syncObj) { Count++; } } }
class Program { static void Main(string[] args) { CounterNoLock counterNoLock = new CounterNoLock(); Thread t1 = new Thread(() => { TestCounter(counterNoLock); }); t1.Name = "t1"; Thread t2 = new Thread(() => { TestCounter(counterNoLock); }); t2.Name = "t2"; Thread t3 = new Thread(() => { TestCounter(counterNoLock); }); t3.Name = "t3"; t1.Start(); t2.Start(); t3.Start(); t1.Join(); t2.Join(); t3.Join(); Console.WriteLine($"没有锁的计数器结果:{counterNoLock.Count}"); CounterWithLock counterWithLock = new CounterWithLock(); Thread tt1 = new Thread(() => { TestCounter(counterNoLock); }); tt1.Name = "tt1"; Thread tt2 = new Thread(() => { TestCounter(counterNoLock); }); tt2.Name = "tt2"; Thread tt3 = new Thread(() => { TestCounter(counterNoLock); }); tt3.Name = "tt3"; tt1.Start(); tt2.Start(); tt3.Start(); tt1.Join(); tt2.Join(); tt3.Join(); Console.WriteLine($"有锁的计数器结果:{counterWithLock.Count}"); Console.ReadKey(); } static void TestCounter(CounterBase counter) { for (int i = 0; i < 100000; i++) { counter.Increase(); counter.Decrease(); } } }
Monitor
public class Player { public string Name { get; private set; } public int Atk { get; private set; } public Player(string name, int atk) { Name = name; Atk = atk; } public void Attack(YaoGuai yaoGuai) { while(yaoGuai.Blood > 0) { Console.WriteLine($"我是{Name},我来打妖怪~"); yaoGuai.BeAttacked(Atk); } } }
public class PlayerWithMonitor { public string Name { get; private set; } public int Atk { get; private set; } public PlayerWithMonitor(string name, int atk) { Name = name; Atk = atk; } public void Attack(YaoGuai yaoGuai) { while (yaoGuai.Blood > 0) { Monitor.Enter(yaoGuai); Console.WriteLine($"我是{Name},我来打妖怪~"); yaoGuai.BeAttacked(Atk); Monitor.Exit(yaoGuai); } } }
public class YaoGuai { public int Blood { get; private set; } public YaoGuai(int blood) { Blood = blood; Console.WriteLine($"我是妖怪,我有{Blood}滴血!"); } public void BeAttacked(int attack) { if (Blood > 0) { Blood = Blood - attack; if (Blood < 0) { Blood = 0; } } Console.WriteLine($"我是妖怪,我剩余{Blood}滴血!"); } }
class Program { static void Main(string[] args) { YaoGuai yaoGuai = new YaoGuai(1000); Player p1 = new Player("孙悟空", 300); Player p2 = new Player("猪八戒", 180); Thread t1 = new Thread(() => { p1.Attack(yaoGuai); }); Thread t2 = new Thread(() => { p2.Attack(yaoGuai); }); t1.Start(); t2.Start(); t1.Join(); t2.Join(); Console.WriteLine("==============================="); YaoGuai yaoGuai2 = new YaoGuai(1000); PlayerWithMonitor p3 = new PlayerWithMonitor("孙悟空", 300); PlayerWithMonitor p4 = new PlayerWithMonitor("猪八戒", 180); Thread t3 = new Thread(() => { p3.Attack(yaoGuai2); }); Thread t4 = new Thread(() => { p4.Attack(yaoGuai2); }); t3.Start(); t4.Start(); t3.Join(); t4.Join(); Console.ReadKey(); } }