最近在解决问题的时候不得不使用线程,从而接触到了STA和MTA,度娘给的解释大多语焉不详。在WikiPedia上面看到了比较清楚的描述,趁着能访问的间隙麻利的摘抄下来分享和自我提升。
大意就是单线程单元访问外部是串行的,在前一个任务完全结束之前不会进行下一个任务(an object is always executed to completion before another is invoked),开发者一般情况下可以不用担心竞争和死锁等问题(The developer therefore does not need to worry about thread locking or race conditions.)。
线程模式分为STA(Single Threaded Apartment) 单线程单元 和 MTA 多线程单元(Multi-Threaded Apartment)。任何一个WPF程序,Main方法前必须有一个[STAThread]特性,否则编译会失败。这个特性用来申明该应用程序的初始线程模型为STA,以便和COM兼容。STA是.NET之前,旧的COM年代的词汇。
1.介绍
STA线程单元的运行方式称为Object-per-Client模式,就是在COM库初始化的时候创建一个内存结构,然后让它和调用CoInitialize的线程相关联。这个内存结构针对每个线程都会有一个。支持STA的COM对象只能在创建它的线程里被使用,其它线程如果再创建它就会失败。在STA线程模式中,对线程的所有调用都放到一个队列中,然后逐个处理这些调用。因此,STA线程永远不会同时执行多个方法。STA线程有自己的专有数据,它们不会在线程之间共享数据。这种特征使这一线程模式非常安全,避免了数据的损坏和同步问题。
MTA多线程单元,COM库在进程中创建一个内存结构,这个内存结构在整个进程中只能有一个,然后让它和调用CoInitializeEx的线程相关联。支持MTA的COM对象可以在任意线程里被使用。多个针对它的调用都会被封装成为消息。COM运行时不提供同步,允许多个线程同时调用COM对象。因此,COM对象需要执行它们自己的同步,以防止来自多个线程的同步访问,产生竞争条件。
2.区别
在同一个单元中,单线程单元(STA)访问外部是串行的,在前一个任务完全结束之前不会进行下一个任务,而MTA单元则可以同时运行多个线程,并使用所有可用的共享数据,由于MTA模式支持同时执行多个线程,所以调用者应负责同步多个线程之间的全局数据。
其实STA和MTA是COM规定的一套线程模型,用于保障多线程情况下你的组件代码的同步。比如说有一个COM对象它内部有一个静态变量 gHello,那么这个对象无论生成多少实例对于gHello在内存中只能有一份,那么如果有两个不同的实例在两个线程里面同时去读写它,就有可能出错,所以就要就要有种机制进行同步保护,STA或者MTA就是这种机制。