引用(http://www.cnblogs.com/luxiaoxun/p/3280146.html)

一、使用线程的好处  

1.可以使用线程将代码同其他代码隔离,提高应用程序的可靠性。

2.可以使用线程来简化编码

3.可以使用线程来实现并发执行

二、基础知识

1.进程与线程:进程作为操作系统执行程序的基本单位,拥有应用程序的资源,进程包含线程,进程的资源被线程共享,线程不拥有资源。

2.前台线程和后台线程:通过用Thread类新建线程默认为前台线程。当所有前台线程关闭时,所有的后台线程也会被直接终止,不会抛异常。

3.挂起(Suspend)和唤醒(Resume):由于线程的执行顺序和程序的执行情况不可预知,所以使用挂起和唤醒容易发生死锁的情况,在实际应用中应该尽量少用。

4.阻塞线程:Join,阻塞调用线程,直到该线程终止。

5.终止线程:Abort:抛出 ThreadAbortException 异常让线程终止,终止后的线程不可唤醒。Interrupt:抛出 ThreadInterruptException 异常让线程终止,通过捕获异常可以继续执行。

6.线程优先级:AboveNormal BelowNormal Highest Lowest Normal,默认为Normal。

三、线程的使用

线程函数通过委托传递,可以不带参数,也可以带参数(只能有一个参数),可以用一个类或结构体封装参数。

namespace Test
{
class Program
{
static void Main(string[] args)
{
Thread t1 = new Thread(new ThreadStart(TestMethod));
Thread t2 = new Thread(new ParameterizedThreadStart(TestMethod));
t1.IsBackground = true;
t2.IsBackground = true;
t1.Start();
t2.Start("hello");
Console.ReadKey();
} public static void TestMethod()
{
Console.WriteLine("不带参数的线程函数");
} public static void TestMethod(object data)
{
string datastr = data as string;
Console.WriteLine("带参数的线程函数,参数为:{0}", datastr);
}
}
}

四、线程池

由于线程的创建和销毁需要耗费一定的开销,过多的使用线程会造成内存资源的浪费,出于对性能的考虑,于是引入了线程池的概念。线程池维护一个请求队列,线程池的代码从队列提取任务,然后委派给线程池的一个线程执行,线程执行完不会被立即销毁,这样既可以在后台执行任务,又可以减少线程创建和销毁所带来的开销。

namespace Test
{
class Program
{
static void Main(string[] args)
{
//将工作项加入到线程池队列中,这里可以传递一个线程参数
ThreadPool.QueueUserWorkItem(TestMethod, "Hello");
Console.ReadKey();
} public static void TestMethod(object data)
{
string datastr = data as string;
Console.WriteLine(datastr);
}
}
}

五、Task 类

使用ThreadPool的QueueUserWorkItem()方法发起一次异步的线程执行很简单,但是该方法最大的问题是没有一个内建的机制让你知道操作什么时候完成,有没有一个内建的机制在操作完成后获得一个返回值。为此,可以使用System.Threading.Tasks中的Task类。

构造一个Task<TResult>对象,并为泛型TResult参数传递一个操作的返回类型。

namespace Test
{
class Program
{
static void Main(string[] args)
{
Task<Int32> t = new Task<Int32>(n => Sum((Int32)n), );
t.Start();
t.Wait();
Console.WriteLine(t.Result);
Console.ReadKey();
} private static Int32 Sum(Int32 n)
{
Int32 sum = ;
for (; n > ; --n)
checked{ sum += n;} //结果太大,抛出异常
return sum;
}
}
}

一个任务完成时,自动启动一个新任务。
一个任务完成后,它可以启动另一个任务,下面重写了前面的代码,不阻塞任何线程。

namespace Test
{
class Program
{
static void Main(string[] args)
{
Task<Int32> t = new Task<Int32>(n => Sum((Int32)n), );
t.Start();
//t.Wait();
Task cwt = t.ContinueWith(task => Console.WriteLine("The result is {0}",t.Result));
Console.ReadKey();
} private static Int32 Sum(Int32 n)
{
Int32 sum = ;
for (; n > ; --n)
checked{ sum += n;} //结果溢出,抛出异常
return sum;
}
}
}

六、委托异步执行

委托的异步调用:BeginInvoke() 和 EndInvoke()

namespace Test
{
public delegate string MyDelegate(object data);
class Program
{
static void Main(string[] args)
{
MyDelegate mydelegate = new MyDelegate(TestMethod);
IAsyncResult result = mydelegate.BeginInvoke("Thread Param", TestCallback, "Callback Param"); //异步执行完成
string resultstr = mydelegate.EndInvoke(result);
} //线程函数
public static string TestMethod(object data)
{
string datastr = data as string;
return datastr;
} //异步回调函数
public static void TestCallback(IAsyncResult data)
{
Console.WriteLine(data.AsyncState);
}
}
}

七、线程同步

  1)原子操作(Interlocked):所有方法都是执行一次原子读取或一次写入操作。

  2)lock()语句:避免锁定public类型,否则实例将超出代码控制的范围,定义private对象来锁定。

  3)Monitor实现线程同步

    通过Monitor.Enter() 和 Monitor.Exit()实现排它锁的获取和释放,获取之后独占资源,不允许其他线程访问。

    还有一个TryEnter方法,请求不到资源时不会阻塞等待,可以设置超时时间,获取不到直接返回false。

  4)ReaderWriterLock

    当对资源操作读多写少的时候,为了提高资源的利用率,让读操作锁为共享锁,多个线程可以并发读取资源,而写操作为独占锁,只允许一个线程操作。

  5)事件(Event)类实现同步

    事件类有两种状态,终止状态和非终止状态,终止状态时调用WaitOne可以请求成功,通过Set将时间状态设置为终止状态。

    1)AutoResetEvent(自动重置事件)

    2)ManualResetEvent(手动重置事件)

  6)信号量(Semaphore)

      信号量是由内核对象维护的int变量,为0时,线程阻塞,大于0时解除阻塞,当一个信号量上的等待线程解除阻塞后,信号量计数+1。

      线程通过WaitOne将信号量减1,通过Release将信号量加1,使用很简单。

  7)互斥体(Mutex)

      独占资源,用法与Semaphore相似。

  8)跨进程间的同步

      通过设置同步对象的名称就可以实现系统级的同步,不同应用程序通过同步对象的名称识别不同同步对象。

深入理解C#多线程 -戈多编程的更多相关文章

  1. 《Linux多线程服务端编程:使用muduo C++网络库》上市半年重印两次,总印数达到了9000册

    <Linux多线程服务端编程:使用muduo C++网络库>这本书自今年一月上市以来,半年之内已经重印两次(加上首印,一共是三次印刷),总印数达到了9000册,这在技术书里已经算是相当不错 ...

  2. 第九节:详细讲解Java中的泛型,多线程,网络编程

    前言 大家好,给大家带来详细讲解Java中的泛型,多线程,网络编程的概述,希望你们喜欢 泛型 泛型格式:ArrayList list= new ArrayList(); ArrayList list= ...

  3. 已看1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架、多线程(并发编程)、I/O(NIO)、Socket、JDBC、XML、反射等。[泛型]\

    1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架.多线程(并发编程).I/O(NIO).Socket.JDBC.XML.反射等.[泛型]\1* ...

  4. Java 多线程高并发编程 笔记(一)

    本篇文章主要是总结Java多线程/高并发编程的知识点,由浅入深,仅作自己的学习笔记,部分侵删. 一 . 基础知识点 1. 进程于线程的概念 2.线程创建的两种方式 注:public void run( ...

  5. 多线程高并发编程(3) -- ReentrantLock源码分析AQS

    背景: AbstractQueuedSynchronizer(AQS) public abstract class AbstractQueuedSynchronizer extends Abstrac ...

  6. Linux多线程服务端编程一些总结

    能接触这本书是因为上一个项目是用c++开发基于Linux的消息服务器,公司没有使用第三方的网络库,卷起袖子就开撸了.个人因为从业经验较短,主 要负责的是业务方面的编码.本着兴趣自己找了这本书.拿到书就 ...

  7. 《Linux 多线程服务端编程:使用 muduo C++ 网络库》电子版上市

    <Linux 多线程服务端编程:使用 muduo C++ 网络库> 电子版已在京东和亚马逊上市销售. 京东购买地址:http://e.jd.com/30149978.html 亚马逊Kin ...

  8. 重新想象 Windows 8 Store Apps (44) - 多线程之异步编程: 经典和最新的异步编程模型, IAsyncInfo 与 Task 相互转换

    [源码下载] 重新想象 Windows 8 Store Apps (44) - 多线程之异步编程: 经典和最新的异步编程模型, IAsyncInfo 与 Task 相互转换 作者:webabcd 介绍 ...

  9. 重新想象 Windows 8 Store Apps (45) - 多线程之异步编程: IAsyncAction, IAsyncOperation, IAsyncActionWithProgress, IAsyncOperationWithProgress

    [源码下载] 重新想象 Windows 8 Store Apps (45) - 多线程之异步编程: IAsyncAction, IAsyncOperation, IAsyncActionWithPro ...

随机推荐

  1. JAVA运行内部类的main方法

    运行内部类的main方法 定义两个线程: 一个线程的名字"thread1",线程功能输出1~10的阶乘. 另一个线程的名字"thread2",线程功能输出线程的 ...

  2. Mybatis值ResultMap的使用详解

    Mybatis的定义 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis ...

  3. Day 15 文件打包与压缩

    1.什么是文件压缩? 将多个文件或目录合并成为一个特殊的文件.比如: 搬家...脑补画面 img. 2.为什么要对文件进行压缩? 当我们在传输大量的文件时,通常都会选择将该文件进行压缩,然后在进行传输 ...

  4. AsyncLocal和Async原理解读

    AsyncLocal 的实现很简单,将AsyncLocal实例和当前线程的值以键值对的形式保存在Thread.CurrentThread.ExecutionContext.m_localValues. ...

  5. Ubuntu python-matplotlib安装couldn't connect to display ":0.0"

    先卸载旧的matplotlib库(sudo pip3 uninstall matplotlib),再利用命令 sudo apt-get install python-matplotlib安装,自动安装 ...

  6. Leetcode 121.买股票的最佳时机

    题目描述: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股票前卖出 ...

  7. Android Studio [Toast]

    ToastActivity.java package com.xdw.a122; import android.support.v7.app.AppCompatActivity; import and ...

  8. 删除pdf中的链接

    在Acrobat中打开pdf文件,然后:编辑→首选项→一般→自动从文本检测URL,把此处的对勾去掉,以后就不会变为食指按的形状了! 还有以下的方法 方法1:“高级(A)”→“链接(L)”→“删除文档中 ...

  9. java架构之路-(分布式zookeeper)zookeeper集群配置和选举机制详解

    上次博客我们说了一下zookeeper的配置文件,以及命令的使用https://www.cnblogs.com/cxiaocai/p/11597465.html.我们这次来说一下我们的zookeepe ...

  10. html实现打印预览效果

    前面说到利用lodop插件进行打印设置,那个应用于打印快递面单,或者跟快递面单相似场景的情况. 今天的利用html快速打印出A4纸大小的场景,例如:合同.静态文本等. 效果如下: 方式一 1.设置di ...