tomcat 线程模型

一、线程模型:

1、BIO: 每个请求都会创建一个线程。

2、NIO: 多路复用选择器(select),由 select 分配线程给它,线程读取后立刻会被释放。

3、APR:Apache Protable Runtime/Apache 可移植运行库

4、AIO: 异步非阻塞式IO, jdk1.7后支持,Tomcat8 之后支持。

二、Tomcat 配置参数:

1、keepAliveTimeout: tcp 长连接时间,长连接不会占用线程,但会占用内存。

     maxKeepAliveRequest: 最大的长连接数量。

2、acceptCount: 等待最大队列。

3、enableLookups: 禁用 DNS 查询。可以提高性能。

In-proc 线程模型

11-29

rnCOMDll2 中有 2 个类rnrnBEGIN_OBJECT_MAP(ObjectMap)rnOBJECT_ENTRY(CLSID_ApartmObj3, CApartmObj3)rnOBJECT_ENTRY(CLSID_FeeObj, CFeeObj)rnEND_OBJECT_MAP()rnrnCApartmObj3 线程模型: ApartmentrnCFeeObj 线程模型: Freernrn我打印如下一些线程ID:rnrnCApartmObj3()rnrn char Data[64];rn memset(Data,0,sizeof(Data));rn sprintf(Data,"CApartmObj3\tthread:0x%0x\tthis:0x%x\t",::GetCurrentThreadId(),(void*)this);rn rn std::string strLog = Data;rn strLog += "CApartmObj3()";rn rn g_LogFile.WriteLog(strLog); rnrnrnSTDMETHODIMP CApartmObj3::QueryInfo2(BSTR *pName)rnrn // TODO: Add your implementation code herern rn char Data[64];rn memset(Data,0,sizeof(Data));rn sprintf(Data,"CApartmObj3\tthread:0x%0x\tthis:0x%x\t",::GetCurrentThreadId(),(void*)this);rn rn std::string strLog = Data;rn strLog += "QueryInfo2()";rn rn g_LogFile.WriteLog(strLog);rn rn rn *pName = _bstr_t("CApartmObj3::QueryInfo2 test........").copy();rn rn return S_OK;rnrnrnCFeeObj()rnrn char Data[64];rn memset(Data,0,sizeof(Data));rn sprintf(Data,"CFeeObj\tthread:0x%0x\tthis:0x%x\t",::GetCurrentThreadId(),(void*)this);rn rn std::string strLog = Data;rn strLog += "CFeeObj()";rn rn g_LogFile.WriteLog(strLog); rnrnrnSTDMETHODIMP CFeeObj::QueryInfo2(BSTR *pName)rnrn // TODO: Add your implementation code herern rn char Data[64];rn memset(Data,0,sizeof(Data));rn sprintf(Data,"CFeeObj\tthread:0x%0x\tthis:0x%x\t",::GetCurrentThreadId(),(void*)this);rn rn std::string strLog = Data;rn strLog += "QueryInfo2()";rn rn g_LogFile.WriteLog(strLog);rn rn rn *pName = _bstr_t("CFeeObj::QueryInfo2 test........").copy();rn rn return S_OK;rnrnrn我在测试中调用:rnrnvoid CCOMTestDlg::OnButton1() rnrnrn CoInitialize(NULL);rnrn CLSID clsid;rn HRESULT hr;rn rn CLSIDFromProgID(OLESTR("COMDll2.ApartmObj3"), &clsid);rn rn hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, __uuidof(IUnknown), reinterpret_cast(&pIUnknown2));rn rn rn IApartmObj3 *pApartmObj3;rn rn pIUnknown2->QueryInterface(__uuidof(IApartmObj3),(void**)&pApartmObj3);rn rn pIUnknown2->Release();rn rn rn BSTR Name2;rn pApartmObj3->QueryInfo2(&Name2);rn rn _bstr_t bstrName22(Name2,false);rn rn rn MessageBox(bstrName22.operator char*());rnrn //rnrn IUnknown* pIUnknown3;rn rn CLSIDFromProgID(OLESTR("COMDll2.FeeObj"), &clsid);rn rn hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, __uuidof(IUnknown), reinterpret_cast(&pIUnknown3));rn rn rn IFeeObj *pFeeObj;rn rn pIUnknown3->QueryInterface(__uuidof(IFeeObj),(void**)&pFeeObj);rn rn pIUnknown3->Release();rn rn rn BSTR Name23;rn pFeeObj->QueryInfo2(&Name23);rn rn _bstr_t bstrName23(Name23,false);rn rn rn MessageBox(bstrName23.operator char*());rnrnrn pApartmObj3->Release();rnrn pFeeObj->Release();rnrn CoUninitialize();rnrnrnrnrn最后日志如下:rn[2007-11-29 17:03:36] main thread:0x814rn[2007-11-29 17:03:36] CApartmObj3 thread:0x814 this:0x18b1940 CApartmObj3()rn[2007-11-29 17:03:36] CApartmObj3 thread:0x814 this:0x18b1940 QueryInfo2()rn[2007-11-29 17:03:36] CFeeObj thread:0x218 this:0x18b1750 CFeeObj()rn[2007-11-29 17:03:36] CFeeObj thread:0x7c0 this:0x18b1750 QueryInfo2()rnrn//rn[2007-11-29 17:41:40] main thread:0x610rn[2007-11-29 17:41:40] CApartmObj3 thread:0x610 this:0x18b1940 CApartmObj3()rn[2007-11-29 17:41:40] CApartmObj3 thread:0x610 this:0x18b1940 QueryInfo2()rn[2007-11-29 17:41:40] CFeeObj thread:0x818 this:0x18b1750 CFeeObj()rn[2007-11-29 17:41:40] CFeeObj thread:0x850 this:0x18b1750 QueryInfo2()rnrnmain thread : 是 DllMain-> DLL_PROCESS_ATTACH 记录下来的rnrn发现 CFeeObj 在 0x218 线程中创建, QueryInfo2() 在 0x7c0 被调用,这是为什么?rnrn

一点心得:组件的线程模型

05-16

关于组件的线程模型rnrn一,两种线程模型rn STA(Single Threaded Apartment)rn  在STA模型中,一个Apartment里只允许有一个线程,可以有多个实例,一个进程中可以有多个STA。每个STA里都必须有消息处理部分。所有对实例的访问都在WINDOWS的消息传递机制下,被线程串行化了。套间与套间之间可以并发执行。rnrn MTA(Multiple Threaded Apartment)rn  在MTA模型中,一个Apartment中可以有多个线程,但是一个进程中只有一个MTA。MTA中不需要消息处理。rnrn (其实在WINDOWS2000还有第三种模型NTA,由于暂时用不到那么高级的功能特性,因些没有去了解和掌握它。)rn 任何要用到COM的线程,都需要标明它的线程模型,而且一旦标明线程模型,线程的同步性便不能更改。很明显,客户端和服务端都需要标明其线程模型。rnrn二,线程模型的联系rn 这里只考虑进程外服务。由于进程外服务和客户程序属于不同的进程,从而必定属于不同的APARTMENT,而COM规定,套间(Inter-apartment)联系必须列集(Marshal)。也就是说不论客户与服务组件联系肯定要通过列集,而列集可以掩盖它们的不同的线程模型。rnrn 在STA中,由于只有一个线程,线程中的多个实例会相互干扰。如果客户端是STA,那么其中所有实例的方法必定完全是顺序执行的,这很容易理解。如果服务端是STA,那么所有客户对组件方法的调用也都是串行的,也就是说,即使客户端是并行调用一个实例的一些方法,实际执行时仍是串行执行的。除非客户端和服务端都是MTA,在一个客户端才能实现并行访问。当然,如果服务端是MTA,而客户端是STA,那么多个客户的访问是并行的,而在一个客户内部的访问是串行的。rnrn三,组件的线程模型rn 组件的线程模型分为四种:Single, Apartment, Both, Free。简单地说,它们分别对应:STA(main),STA,STA and MTA, MTA。对象的线程模型的含义是“它生活在什么样的线程模型里”,就好像划成分一样,一出生就确定,然后就不能再改变。rnrn 根据MSDN上的说明,尽量不要用Single和Free,所以这里只讨论Apartment和Both。Apartment类的对象只能生活在STA中,如果服务程序本身是STA,那么它就不得不重新为每个实例生成一个新的Apartment。由于服务程序和组件生活在不同的套间,每次访问都不得不进行套间切换和列集,这样是非常低效的。但如果服务程序是STA,那么就可以直接调用了。Both类的对象即可以在STA中,也可以在MTA中,不管服务程序属于哪一类,都可以直接调用,因此非常高效。rnrn Apartment的优势在于它不必是线程安全的,但对于全局变量和静态变量,仍然要提供同步保持机制。Both类的对象必须是线程完全的。

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试