class Program
{
static void Main(string[] args)
{
/**
//前台线程和后台线程组成线程 所以每一个线程都有一个IsBackground
//前台线程必须执行完程序才会退出
//后台程序在程序退出时一并退出
//当创建一个线程时默认是后台线程
Console.WriteLine(Thread.CurrentThread.IsBackground);
Console.WriteLine(Thread.GetCurrentProcessorId().ToString());
Thread th = new Thread(_=>{
Thread t = _ as Thread;
//注释以后前台线程变后台线程 那么现在你在console.read之后程序直接执行完毕 不会再执行 "子线程结束"
//t.IsBackground = true;
Console.WriteLine("子线程开始工作");
Console.WriteLine(t?.IsBackground);
Console.WriteLine(Thread.GetCurrentProcessorId().ToString());
//挂起线程取决于此条命令在哪个线程执行
Thread.Sleep(2000);
Console.WriteLine("子线程结束!");
});
th.Start(th);
Thread.Sleep(1000);
Console.WriteLine("主进程完毕");
Console.Read();
*/
//设置优先级(提供线程被调用的概率)
// ThreadPriority();
//Abort的使用
//ThreadAbort();
//ThreadJion();
ThreadLock();
Console.Read();
}
/// <summary>
/// 线程优先级依赖于windows内部的线程调度
/// 线程如果处于等待状态会释放掉他所持有的cpu 即使没有手动释放CPU也会被线程调度器抢占CPU
/// 如果多个线程有相同的优先级 那么windows会为我们创建一个同优先级的队列然后循环执行
/// 线程的优先级是动态调整的 所以低优先级的也会随着时间提升
/// 也就是说 手动提升线程的优先级 对系统而言只是提高了被调用的概率
/// </summary>
static void ThreadPriority() {
Thread thread = new Thread(()=> {
Console.WriteLine("test thread");
});
Console.WriteLine(thread.Priority);
thread.Start();
thread.Priority = System.Threading.ThreadPriority.Highest;
Console.WriteLine(thread.Priority);
Console.Read();
}
static void ThreadAbort() {
Thread t = new Thread(_=> {
Console.WriteLine("线程:"+Thread.CurrentThread.Name+" 终止");
try {
//使用Abort的方式停止线程会抛出异常
Thread.CurrentThread.Abort();
}
catch (Exception ex) {
//当Abort抛出异常时可以用ResetAbort取消停止
//可以尝试注释词条查看效果
Thread.ResetAbort();
}
Console.WriteLine("你看我打印不");
});
t.Name = "testThread";
t.Start();
}
/// <summary>
/// 阻塞其他线程(包括主线程) 直到找个线程执行完才会执行其他线程
/// 通俗的说 就是这个join你放到哪个线程阻塞哪个线程
/// </summary>
static void ThreadJion() {
Thread minThree = new Thread(() => print(3000, "线程minThread"));
//挂2000
Thread th = new Thread(()=>print(2000,"线程th"));
//挂1000
Thread th1 = new Thread(() => {
minThree.Start();
//让线程 minthree阻塞本线程
minThree.Join();
print(1000, "线程th1");
});
th.Start();
th1.Start();
//让th1阻塞主线程
th1.Join();
//此时minthree阻塞了th1 th先被打印了 而后打印了minthree 和 th1 再然后打印汉字
Console.WriteLine("我是主线程我想看看谁先执行完毕");
}
public static void print(int time,string str) {
Thread.Sleep(time);
Console.WriteLine(str);
}
/// <summary>
/// lock关键字锁住某个资源让让线程有序使用
/// </summary>
public string name = "";
public static void ThreadLock() {
Program pg = new Program();
pg.name = "尹程";
//开两个线程抢下资源
Thread t1 = new Thread(()=>printName(pg,"1"));
Thread t2 = new Thread(() => printName(pg,"2"));
t1.Start();
//提升一下被调用的概率
t1.Priority = System.Threading.ThreadPriority.AboveNormal;
t2.Start();
}
private static object obj;
public static void printName(object pg,string mark) {
//锁住资源 注释掉lock多执行几次看看效果就明白了
//锁住了所有program类的实例
lock (typeof(Program)) {
for (int i = 0; i < 3; i++)
{
Console.WriteLine((pg as Program).name + " " + mark);
}
}
//我这里所著的是一个类的实例对象
//不要锁字符串 字符串被C#特殊处理了 lock("某个字符串变量")与lock(typeof(string))是一样的效果
lock (pg) {
}
//锁住一个私有静态的全局变量
//这样搞主要是为了静态的单例使用
//比如pureMVC把几个层的单例全部放在寄存器里读取 特意锁了个私有的静态变量 保证单例实例化的时候不会被其他线程同时执行
lock (obj) {
}
}
public static void AboutMonitor() {
//lock在使用时会被CLR(C#的运行环境)解释为Monitor静态类
//lock(obj){(这个括号相当于)
Monitor.Enter(obj);
//释放掉obj身上的锁 注意 解锁时 一定要在 Enter和Exit之间
Monitor.Wait(obj);
//只能锁Enter中锁住的资源
Monitor.Pulse(obj);
//} (这个括号相当于)
Monitor.Exit(obj);
}
}
转载于:https://www.cnblogs.com/chenggg/p/10781153.html
相关资源:C#多线程List的非线程安全性