- 一、多线程
-
- 1、线程的基础概念
- 2、线程的创建
- 3、线程的运行
- 3、线程的终止及休眠
- 4、完整代码
一、多线程
1、线程的基础概念
- (1)进程:进程是操作系统进行资源分配和管理的基本单位,可以看作是数据集合上的一次运行活动
- (2)线程:线程是操作系统能进行运算调度的最小单位,线程包含在进程中,是进程实际运行单位
2、线程的创建
- (1)线程类 Thread,需要引用命名空间 using System.Threading
- (2)创建线程实列 Thread t = new Thread(传入一个委托)
(A)该线程要执行的内容要封装在传入的委托之中 (B)允许传入参数,这里Thread的参数类型的委托为ParameterizedThreadStart,而他的参数类型固定为 object, 因此实际传入的参数可以是任意类型

3、线程的运行
- (1)线程的运行 Thread.start()
有参数则传入对应参数,反之不填
运行结果 
- (2)在多线程中,线程之间会共享数据
(A)在多线程中,线程会同时操作同一片内存空间,因此可能会导致数据串联的现象,如在下面的代码中,会出现以下问题
(a)问题:两个线程可能会同时取出队列中的同一元素 (b)问题:队列取空
左图结果为:两个线程同时取出队列中的同一元素c 右图结果为:线程thread1已经取出最后一个元素,而thread2仍然在取队列中的元素导致报错 
(B)解决方法,加入lock(引用类型参数)
运行结果 
- (3)如何将线程设置为后台线程
(A)为什么设置为后台线程
因为当新开线程是while死循环时,若此时该线程为前台线程,那么将会导致进程无法正常关闭 而设置为后台线程则会避免这个情况,因为在前台线程关闭时,后台线程会自动关闭
(B)怎么设置

3、线程的终止及休眠
- (1)线程休眠:Thread.sleep()
参数为整型,单位是ms,其中1000ms = 1s
- (1)线程终止
(a)等待线程执行完毕Thread.Join()

(b)通过bool终止线程
通过一个bool类型的线程结束信号来进行线程的终止
运行结果 
4、完整代码
- 线程相关的完整代码
using System.Security.Cryptography.X509Certificates;
namespace Article_8_多线程
{
class Program
{
//定义一个bool类型的线程结束信号
static bool stopThread = false;
#region 一.线程的基础概念
//(1)进程:
//(2)线程:线程是操作系统能进行运算调度的最小单位,线程包含在进程中,是进程实际运行单位
#endregion
#region 2.线程的创建
//(1)线程类 Thread,需要引用命名空间 using System.Threading
//(2)创建线程实列 Thread t = new Thread(传入一个委托)
// (a)该线程要执行的内容要封装在函数之中
static Thread t = new Thread(() =>
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(500);
Console.WriteLine("我是线程t中的逻辑,标识为{0}",i);
}
Console.WriteLine("===线程t运行结束===");
});
static Thread t2 = new Thread((object o) =>
{
Console.WriteLine("参数为{0}",o);
for (int i = 0; i < 10; i++)
{
Thread.Sleep(500);
Console.WriteLine("我是线程t2中的逻辑,标识为{0}", i);
}
Console.WriteLine("===线程t2运行结束===");
});
#endregion
#region 3.线程的运行
public static void Main(string[] args)
{
//(1)线程的运行 t.Start()
Console.WriteLine("===主线程开始运行===");
// (a)无参
//t.Start();//线程t开始运行
// (b)有参
//t2.Start(1);
//(2)在多线程中,线程之间会共享数据
// 因此可能会出现线程之前出现串联的现象,如在下述队列中,可能会出现同时取出同一个的元素
// 解决方法,加lock(引用类型参数)
Queue<string> queue = new Queue<string>();
queue.Enqueue("a");
queue.Enqueue("b");
queue.Enqueue("c");
queue.Enqueue("d");
queue.Enqueue("e");
queue.Enqueue("f");
queue.Enqueue("g");
queue.Enqueue("h");
queue.Enqueue("i");
//加锁,首先定义一个引用类型变量
string queueLock = "";
Thread thread1 = new Thread(() =>
{
Console.WriteLine("===线程thread1启动===");
//其次,在对应逻辑处加上lock
lock (queueLock)
{
while (queue.Count > 0)
{
Thread.Sleep(5);
string item = queue.Dequeue();
Console.WriteLine($"线程thread1 取出:{item} | 剩余元素数:{queue.Count}");
}
}
Console.WriteLine("===线程thread1结束===");
});
Thread thread2 = new Thread(() =>
{
Console.WriteLine("===线程thread2启动===");
lock (queueLock)
{
while (queue.Count > 0)
{
Thread.Sleep(5);
string item = queue.Dequeue();
Console.WriteLine($"线程thread2 取出:{item} | 剩余元素数:{queue.Count}");
}
}
Console.WriteLine("===线程thread2结束===");
});
thread1.Start();
thread2.Start();
//(3)如何将线程设置为后台线程
// (a)为什么设置为后台线程
// 因为当新开线程是while死循环时,若此时该线程为前台线程,那么将会导致进程无法正常关闭
// 而设置为后台线程则会避免这个情况,因为在前台线程关闭时,后台线程会自动关闭
// (b)怎么设置
//法一:线程实列化时设置
Thread t3 = new Thread(() => { }) { IsBackground=true};
//法二:实列化后设置
t3.IsBackground=true;
#region 3.线程的终止及休眠
//(a)等待线程执行完毕Thread.Join()
thread1.Join();
thread2.Join();
Console.WriteLine();
//(b)通过bool终止线程
Thread bool_End_Theard = new Thread(() =>
{
int count = 0;
Console.WriteLine("bool_End_Theard:开始执行");
// 循环执行,每次检查停止标志
while (!stopThread)
{
Console.WriteLine("bool_End_Theard:正在执行,计数="+count);
count++;
Thread.Sleep(500);
}
// 检测到停止信号退出
Console.WriteLine("bool_End_Theard:检测到停止信号,退出");
});
Console.WriteLine("===== 演示:通过bool标志位终止线程 =====");
bool_End_Theard.Start();
Thread.Sleep(3000);
stopThread = true;//将线程终止信号设为true
bool_End_Theard.Join();
//(c)通过Thread.Interrupt终止
#endregion
}
#endregion
}
}

![打卡信奥刷题(3676)用C++实现信奥题 P12271 [蓝桥杯 2024 国 Python B] 括号与字母-171主机测评](https://www.171host.com/wp-content/uploads/2026/11/20261107050125-6aeeb0a5a5ade-220x150.png)