C# 线程知识汇总
一、基本概念
进程(process)是windows系统中你的一个基本概念,它包含着一个运行程序所需要的资源。一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或者多个线程。线程是操作系统分配处理器时间的基本单元吗,在进程中可以有多个线程同时执行代码。进程之间是相互独立的,一个进程无法访问另外一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行。进程可以理解为一个程序的边界。是程序的一个实例,是程序的一次动态执行过程。
线程(Thread)是进程中的基本执行单元,是操作系统分配CPU时间的基本单位,一个进程可以包含若干个线程,在进程入口执行的第一个线程被视为这个进程的主线程。在.NET应用程序中,都是以Main()方法作为入口的,当调用此方法时系统就会自动创建一个主线程。
多线程的优点:可以同时完成多个任务;可以使程序的响应速度更快;可以让占用大量处理时间的任务或当前没有进行处理的任务定期将处理时间让给别的任务;可以随时停止任务;可以设置每个任务的优先级以优化程序性能。
然而,多线程虽然有很多优点,但是也必须认识到多线程可能存在影响系统性能的不利方面,才能正确使用线程。不利方面主要有如下几点:
(1)线程也是程序,所以线程需要占用内存,线程越多,占用内存也越多。
(2)多线程需要协调和管理,所以需要占用CPU时间以便跟踪线程。
(3)线程之间对共享资源的访问会相互影响,必须解决争用共享资源的问题。
(4)线程太多会导致控制太复杂,最终可能造成很多程序缺陷。
二、实例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ThreadDemo
{
public class ThreadTest
{
public void Run()
{
Console.WriteLine("这是无参数,无返回值的方法");
} /// <summary>
/// 方法里面的参数类型必须是Object类型
/// </summary>
/// <param name="paramer"></param>
public void Run(object paramer)
{
Console.WriteLine("这是有参数无返回值的方法,参数是:{0}",paramer.ToString());
} public int Run(int paramer)
{
Console.WriteLine("这是有参数有返回值的方法,参数是:{0}",paramer);
return paramer;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace ThreadDemo
{
class Program
{
public delegate int FunTest(int paramer);
static void Main(string[] args)
{
testClass.run();
ThreadTest test = new ThreadTest();
//调用无参数无返回值
Thread t1 = new Thread(new ThreadStart(test.Run));
t1.Name = "no paramer no result";
t1.Start();
//调用有参数没有返回值
Thread t2 = new Thread(new ParameterizedThreadStart(test.Run));
t2.Name = "paramert an no result";
t2.Start(1);
//调用有参数有返回值
FunTest ft = new FunTest(test.Run);
IAsyncResult result = ft.BeginInvoke(1, null, null);
Console.ReadKey(); }
}
}
三、锁
我们希望在某一个时刻,只有一个线程能执行某一段代码块,这个时候就需要用到锁。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace Lock
{
public class ThreadTest
{
/*
Lock 和Monitor异同:
1.他们都是指在对象上获取排他锁,用于同步代码区
2.Lock关键字是Monitor的一种替换用法,Lock在IL代码中会被翻译承Monitor
所以lock能做的,Monitor肯定能做,Monitor能做的,lock不一定能做
*/
private static object obj = new object();
public static int[] arr = { 1, 2, 3, 4 };
public void LockRun()
{
//加锁之后会按照正常顺序输出
//不加锁顺序被打乱
lock (obj)
{
run();
}
} public void MonitorRun()
{
//lock是monitor的语法糖,最后都会被翻译承下面这个
try
{
Monitor.Enter(obj);
run();
}
catch (Exception)
{ throw;
}
finally
{
Monitor.Exit(obj);
} }
public void run()
{
for (int i = 0; i < arr.Length; i++)
{
Console.WriteLine("当前线程名:" + Thread.CurrentThread.Name + ". value:" + arr[i]);
}
} }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace Lock
{
class Program
{
static void Main(string[] args)
{
ThreadTest test1 = new ThreadTest();
Thread t1 = new Thread(new ThreadStart(test1.LockRun));
t1.Name = "test thread 1";
t1.Start();
ThreadTest test2 = new ThreadTest();
Thread t2 = new Thread(new ThreadStart(test2.LockRun));
t2.Name = "test thread 2";
t2.Start();
ThreadTest test3 = new ThreadTest();
Thread t3 = new Thread(new ThreadStart(test3.MonitorRun));
t3.Name = "test thread 3";
t3.Start();
Console.ReadKey();
}
}
}

四、Monitor
Monitor 是静态类,不能实例化
Monitor背后管理着2个队列:一个就绪队列(ready 队列),还有一个等待队列(waiting队列)
ready队列中保存的就是准备获取锁的线程,就是说,如果某个线程执行了waiting,那么ready队列中的第一个线程就会获得锁,开始运行,同时该线程进入waiting队列的队尾。
ready队列中保存的是准备获取锁的线程。就是说,如果某个线程(记作线程A)执行了Monitor.Wait(),那么ready队列中的第一个线程就会获得锁,开始运行(如果ready队列中没有线程, 那么就没有这个效果);同时线程A自动进入waiting队列中的队尾了。
waiting队列中保存的是正在等待锁定对象状态变化的通知的线程。就是说,如果某个线程执行了Monitor.Pulse(),那么waiting队列中队头的线程就进入ready队列中。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp4
{
class Program
{
static readonly object _locker = new object();
static bool go;
static void Main(string[] args)
{ new Thread(Work).Start();
Console.ReadLine();
lock (_locker)
{
go = true;
Monitor.Pulse(_locker);
}
Thread.Sleep(1000);
Console.ReadKey();
}
static void Work()
{
lock (_locker)
{
while (!go)
{
// 把拥有当前锁的线程放入队列中
Monitor.Wait(_locker);
} }
Console.WriteLine("被唤醒了。");
}
}
}

C# 线程知识汇总的更多相关文章
- [转]【eoeAndroid索引】史上最牛最全android开发知识汇总
一.开发环境搭建 (已完成) 负责人:kris 状态:已完成 所整理标签为:搭建 SDK JDK NDK Eclipse ADT 模拟器 AVD 调试器(DEBUG) DDMS 测试 日志 Logca ...
- Java快速入门-03-小知识汇总篇(全)
Java快速入门-03-小知识汇总篇(全) 前两篇介绍了JAVA入门的一系小知识,本篇介绍一些比较偏的,说不定什么时候会用到,有用记得 Mark 一下 快键键 常用快捷键(熟记) 快捷键 快捷键作用 ...
- 沉淀,再出发:Java基础知识汇总
沉淀,再出发:Java基础知识汇总 一.前言 不管走得多远,基础知识是最重要的,这些知识就是建造一座座高楼大厦的基石和钢筋水泥.对于Java这门包含了编程方方面面的语言,有着太多的基础知识了,从最初的 ...
- Oracle手边常用70则脚本知识汇总
Oracle手边常用70则脚本知识汇总 作者:白宁超 时间:2016年3月4日13:58:36 摘要: 日常使用oracle数据库过程中,常用脚本命令莫不是用户和密码.表空间.多表联合.执行语句等常规 ...
- Oracle 数据库知识汇总篇
Oracle 数据库知识汇总篇(更新中..) 1.安装部署篇 2.管理维护篇 3.数据迁移篇 4.故障处理篇 5.性能调优篇 6.SQL PL/SQL篇 7.考试认证篇 8.原理体系篇 9.架构设计篇 ...
- Vertica 数据库知识汇总篇
Vertica 数据库知识汇总篇(更新中..) 1.Vertica 集群软件部署,各节点硬件性能测试 2.Vertica 创建数据库,创建业务用户测试 3.Vertica 数据库参数调整,资源池分配 ...
- 【转】ACM博弈知识汇总
博弈知识汇总 转自:http://www.cnblogs.com/kuangbin/archive/2011/08/28/2156426.html 有一种很有意思的游戏,就是有物体若干堆,可以是火柴棍 ...
- 最全的jQuery知识汇总
本帖最后由 断天涯大虾 于 2016-12-26 10:22 编辑<ignore_js_op> jQuery是什么? jQuery是javascript编写一个可重用的JavaScript ...
- rxjava源码中的线程知识
rxjava源码中的线程知识 rx的最精简的总结就是:异步 这里说一下以下的五个类 1.Future2.ConcurrentLinkedQueue3.volatile关键字4.AtomicRefere ...
随机推荐
- Eigen与Matlab语法及语义辞典
Eigen为Matlab转换为C++提供了一个简单的语法级别的代码迁移工具. 对一些代码进行了扩充,以便程序由Matlab到Eigen的移植................... 参考链接:http: ...
- 【sqli-labs】 less4 GET - Error based - Double Quotes - String (基于错误的GET双引号字符型注入)
提交id参数 加' http://localhost/sqli/Less-4/?id=1' 页面正常,添加" http://localhost/sqli/Less-4/?id=1" ...
- 函数式编程-将Monad(单子)融入Swift
前言 近期又开始折腾起Haskell,掉进这个深坑恐怕很难再爬上来了.在不断深入了解Haskell的各种概念以及使用它们去解决实际问题的时候,我会试想着将这些概念移植到Swift中.函数式编程范式的很 ...
- C# 根据空格数截取
#region --根据空格数截取 ; ; //循环截取 , }; while (!sr.EndOfStream) { ; i < strTest.Length - ; i++) { ).Tri ...
- 题解 P2605 【[ZJOI2010]基站选址】(From luoguBlog)
线段树优化dp 数组f[i][j]表示在前i个村庄内,第j个基站建在i处的最小费用 根据交线牛逼法和王鹤松式可得方程 f[i][j]=min(f[k][j−1]+cost(k,i)) cost(k,i ...
- BZOJ : [Usaco2013 Nov]Crowded 单调队列
正反两遍个来一次单调队列 DP 即可. Code: #include<cstdio> #include<deque> #include<algorithm> usi ...
- NOIP2016 DAY2 T2蚯蚓
传送门 Description 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳 蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神 ...
- SQLServer · BUG分析 · Agent 链接泄露分析(转载)
背景 SQLServer Agent作为Windows服务提供给用户定期执行管理任务,这些任务被称为Job:考虑应用镜像的场景如何解决Job同步问题,AWS RDS的做法是不予理会,由用户维护Job, ...
- Beautifulsoup提取特定丁香园帖子回复
DataWhale-Task3(Beautifulsoup爬取丁香园) 简要分析 完整代码 结果图 参考资料 简要分析 任务3:爬取丁香园论坛特定帖子,包括帖子主题,帖子介绍,回贴内容(用户名,用户头 ...
- 百度之星2014初赛 - 1002 - Grids
先上题目: Grids Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Tota ...