--Start--
原子操作 --
【不会被线程调度机制打断的最小执行单元】
--End-- 原子操作 --
--Start-- 线程安全包装器 --
【1.对于类中方法实现线程非同步(非线程安全)和同步(线程安全)两种访问机制,避开因单线程造成死锁的性能问题。】
//AccountWrapper类 对 Account 类 的线程安全封装
public class AccountWrapper
{
private Account _a;
///非线程安全
public AccountWrapper()
{
this._a=new Account();
}
///线程安全
public AccountWrapper(Account a)
{
this._a=a;
}
public bool Withdraw(double dnum)
{
lock(_a)
{
return this._a.Withdraw(dnum);
}
}
}
【2.内置同步包装器eg:System.Collections里的ArrayList、Hashtable】
Hashtable h= Hashtable.Synchronized(new Hashtable());
--End--线程安全包装器--
--Start--NET同步支持--
1.Monitor //用于同步代码区
2.Mutex //进程同步&代码区同步
3.AutoResetEvent,ManualResetEvent
4.Interlocked //同步访问一个由多线程共享的变量
Interlocked.Inerement(ref i)
5.SynchronizationAttribute
6.MethodImplattribute //用于 同步代码块
[MethodImpl(MethodImplOptions.Synchronized)]
public void DoSomeWorkSync()
{
}
7.ReaderWriterLock
AcquireReaderLock()
AcquireWriterLock()
ReleaseReaderLock()
ReleaseWriterLock()
8.lock
9.ThreadStaticAttribute 类
【用于静态变量上为每个执行线程创建一个单独变量(非共享变量)】
class ThreadStatic
{
[System.ThreadStaticAttribute()]
public static int x=1; // 有 线程静态变量属性
public static int y=1; // 无 线程静态变量属性
public void Run()
{}
}
public class MainApp
{
public static void Main()
{
ThreadStatic tS=new ThreadStatic();
Thread tX=new Thread(new ThreadStart(tX.Run));
Thread tY=new Thread(new ThreadStart(tY.Run));
tX.Start();
tY.Start();
}
}
--End-- NET同步支持 --
--Start-- 同步VS性能 --
【线程同步需要获得同步锁(消耗系统时间),性能弱于非线程安全】
--End-- 同步VS性能 --
--Start--死锁--
【严防死锁方法之一:避免一次取得多个锁】
--End-- 死锁 --
--Start-- 数据库连接池 --
数据据库连接池应用程序UML描述图
【1.实现池】
ObjectPool类
collectGarbage() 用于处理池中对象回收
GARBAGE_COLLECT常量设置垃圾收集间隔时间(默认为30s)
using System;
using System.Collections;
using System.Timers;
namespace WroxCS
{
public abstract class ObjectPool
{
private long _lastCheckOut; //last Checkout time of any object from the pool
private static Hashtable locked; //Hashtable of the checked-out objects
private static Hashtable unlocked; //Hashtable of avaltable objects
internal static long GARBAGE_INTERVAL=90*1000; //Clean-Up interval (set 90s)
static ObjectPool()
{
locked=Hashtable.Synchronized(new Hashtable());
unlocked=Hashtable.Synchronized(new Hashtable());
}
internal ObjectPool()
{
_lastCheckOut=DateTime.Now.Ticks;
System.Timers.Timer aTimer=new System.Timers.Timer(); //Create a Time to track the expired objects for cleanup
aTimer.Enabled=true;
aTimer.Interval=GARBAGE_IMTERVAL;
aTimer.Elapeed+=new System.Timers.ElapsedEventHandler(CollectGarbage);
}
protected abstract object Create();
protected abstract bool Validate(object o);
protected abstract void Expire(object o);
internal object GetObjectFromPool()
{
long now = DateTime.Now.Ticks;
_lastCheckOut=now;
object o=null;
lock(this)
{
try
{
foreach(DictionaryEntry myEntry in unlocked)
{
o=myEntry.Key;
if(validate(o))
{
unlocked.Remove(o);
locked.Add(o,now);
return(o);
}
else
{
unlocked.Remove(o);
expire(o);
o=null;
}
}
}
catch(exception){}
o= Create();
locked.Add(o,now);
}
return (o);
}
internal void ReturnObjectToPool(object o)
{
if(o!=null)
{
lock(this)
{
locked.Remove(o);
unlocked.Add(o,DateTime.Now.Ticks);
}
}
}
private void CollectGarbage(object sender,System.Timers.ElapsedEventArgs ea)
{
lock(this)
{
object o;
long now=DateTime.Now.Ticks;
IDictionaryEnumerator e=unlocked.GetEnumerator();
try
{
while(e.MoveNext())
{
o=e.Key;
if(now-((long)unlocked[o])>GARBAGE_INTERVAL)
{
unlocked.Remove(o);
Expire(o);
o=null;
}
}
}
catch(Exception){}
}
}
}
}
DBConnectionSingleton类 ,数据库链接对象池的实现方式
--End-- 数据库连接池 --
--Start-- 线程设计规 --
STA线程单元
【运行方式:Object-Per-Client,对所有线程的调用都放到一个队列,逐个出队处理。】
C#[STA ThreadAttribute]static void Main(){}ASP.NET【默认为多线程(MTA模式),加如下代码至页面顶部将在STA线程模式下运行,会降低应用程序的性能。】<%@Page AspCompat="true"%>
线程设计模式
a.主线程和工作线程模式
b.对等线程模式
c.管道线程模式
--End-- 线程设计规划 --
--Start-- CLR --
【公共语言运行时,Common Language Runtime)和Java虚拟机一样也是一个运行时环境(用于创建托管代码环境),它负责资源管理(内存分配和垃圾收集),并保证应用和底层操作系统之间必要的分离。eg:编译、GC、内存管理、、线程池】
--End-- CLR --
--Start-- 线程池 --
【优势】
1.无需为创建线程耗费时间,线程池中线程是现成的(CLR分配),一直处于等待任务分派的装填2.线程生命期结束.net会回收其资源3.线程池根据系统当前的进程,优化线程时间片4.线程池允许启动多个线程,而不必为每个线程设置属性5.线程池允许将状态信息作为一个对象传递给当前执行任务的过程参数6.线程池可以将处理客户请求的线程数量固定为某一个最大值( 默认情况下,每个进程可以产生25个线程池线程,这个数量可以通过编辑mscoree.h文件中的CorSetMaxThreads成员加以改变)
【劣势】
1.任务一旦加入队列,不能人为启动、挂起、终止
2.线程池不适用于又大又长的任务
3.线程池的成本效率比很高,需小心使用池中的线程,线程池的大小应该固定不变
4.线程池中的所有线程都处于多线程单元中(MTA)
5.不能为线程池中的任务设置优先级
6.对任意应用程序域,只能有一个线程池与其关联
7.如果线程池中的一个线程任务被锁定,这个线程将不会呗释放回池中。
【ThreadPool类】
1.BindHandle //该方法将操作系统句柄绑定到线程池中
2.GetAvailableThreads //该方法指出(在达到最大限制值之前)可以添加到任务项队列中的任务数(添加到线程池中的请求数)
public static void GetAvailableThreads(out int workerThreads,out int completionPortthreads)
workerThreads表示线程池中工作线程的数量
completionPortThreads表示异步的 I/O 线程数量
3.GetMaxThreads //该方法指出线程池可以同时排队的请求数量(反回线程池可以处理的并发请求的最大数量)
public static void GetMaxThreads(out int workerThreads,out int completionPortThreads)
WorkerThreads表示线程池中工作线程的数量
CompletionPortThreads表示异步 I/O 线程的数量
4.QueueUserWorkItem //该方法将一个任务项排列到线程池中
public static bool QueueUserWorkItem(WaitCallback callBack)
callBack表示线程池中的线程获得任务项时要调用的委托,返回值true表明方法调用成功
public static bool QueueUserWorkItem(WaitCallback callBack , object state)
callBack表示线程池中的线程获得任务项时要调用的委托,返回值true表明方法调用成功,state表示包含状态的对象,该对象将在线程执行任务时传递给委托
5.RegisterWaitForSingleObject //该方法注册一个委托,他等待一个WaitHandle
6.UnsafeQueueUserWorkItem //这是QueueUserWorkItem()方法的非安全版本
7.UnsafeRegisterWaitForSingleObject //这是RegisterWaitForSingleObject()方法的非安全版本
【Demo 一】
class Program
{
static void Main(string[] args)
{
int m_work_threads;//工作线程数
int m_io_threads;//IO线程数
bool Succ1 = ThreadPool.SetMaxThreads(5, 5);//设置线程池最多自由的线程数,我这里测试必须≥4才能成功(返回true)
ThreadPool.GetMaxThreads(out m_work_threads, out m_io_threads);//获取经过设置之后的最大线程数,顺便查看是否成功
Console.WriteLine("当前最大工作线程数:{0},I/O线程数: {1}-{2}", m_io_threads, m_io_threads, Succ1);
for (int i = 0; i < 10; i++)
{
//线程池管理线程列表
ThreadPool.QueueUserWorkItem(JobForAThread);
}
Thread.Sleep(30);
ThreadPool.GetAvailableThreads(out m_io_threads, out m_io_threads);//获取还剩可用的最大工作,IO线程数目
Console.WriteLine("剩余工作线程数:{0},I/O线程数: {1}", m_io_threads, m_io_threads);
Console.ReadKey();
}
static void JobForAThread(object state)
{
for (int i = 0; i < 1; i++)
{
Console.WriteLine("loop {0},running inside pooled thread {1}", i, Thread.CurrentThread.ManagedThreadId);// 池线程中运行
List<int> list = new List<int>();
list.AddRange(new int[] { 10, 6, 11, 12, 13, 14 });
if (list.Contains<int>(Thread.CurrentThread.ManagedThreadId))
{
Thread.Sleep(4000);
}
Thread.Sleep(50);
}
}
}
【Demo 二】
--End-- 线程池 --
--Start-- MSMQ --
【Message Queue(微软
消息队列)是在多个不同的应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间中的任一位置。】
--End-- MSMQ --
--Start-- 调试跟踪线程 --
Trace Debug BooleanSwitch TraceSwitch
--End-- 调试跟踪线程 --
转载于:https://blog.51cto.com/feelmanc/1250415