❶ 多线程原理有哪些
多线程概述
进程和线程都是操作系统的概念。进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成,进程在运行过程中创建的资源随着进程的终止而被销毁,所使用的系统资源在进程终止时被释放或关闭。
线程是进程内部的一个执行单元。系统创建好进程后,实际上就启动执行了该进程的主执行线程,主执行线程以函数地址形式,比如说main或WinMain函数,将程序的启动点提供给Windows系统。主执行线程终止了,进程也就随之终止。
每一个进程至少有一个主执行线程,它无需由用户去主动创建,是由系统自动创建的。用户根据需要在应用程序中创建其它线程,多个线程并发地运行于同一个进程中。每个线程具有自己的堆栈和自己的 CPU 寄存器副本。其他资源(如文件、静态数据和堆内存)由进程中的所有线程共享。所以线程间的通讯非常方便,多线程技术的应用也较为广泛。但是使用这些公共资源的线程必须同步。Win32 提供了几种同步资源的方式,包括信号、临界区、事件和互斥体。
每个进程都有私有的虚拟地址空间,进程的所有线程共享同一地址空间。每个线程被CPU分配一个时间片,一旦被激活,它正常运行直到时间片耗尽并被挂起,此时,操作系统选择另一个线程进行运行。通过时间片轮转,又出于各个时间片很小(20毫秒级),看起来就像多个线程同时在工作。实际上,只有在多处理器系统上才是真正的在可得到的处理器上同时运行多个线程。基于Win32的应用程序可以通过把给定进程分解(或创建)多个线程挖掘潜在的CPU时间,而且还可以加强应用程序,以使用户提高效率,加强反应能力以及进行后台辅助处理。
在Windows操作系统中,Win32应用程序可以在Windows平台上运行多个实例,每个应用程序实例都是一个独立的进程,而一个进程可以由不止一个线程来实现。对于一个进程来说,当应用程序有几个任务要同时运行时,建立多个线程是有用的。如打印时,利用多线程机制实现多线程,就可在需要打印时创建一个负责完成打印功能的打印线程。创建打印线程之后,系统就变成了多线程。当进行打印时,CPU轮换着分配给这两个线程时间片,所以打印和其他功能一起同时在运行,这就充分利用了CPU处理打印工作之外的空闲时间片,并且避免了用户长久地等待打印时间。这就是所谓的由多线程来实现的多任务,在进行打印任务的同时又可以进行别的任务。要说明的一点是,目前大多数的计算机都是单处理器(CPU)的,为了运行所有这些线程,操作系统为每个独立线程安排一些CPU时间,操作系统以轮换方式向线程提供时间片,这就给人一种假象,好象这些线程都在同时运行。由此可见,如果两个非常活跃的线程为了抢夺对CPU的控制权,在线程切换时会消耗很多的CPU资源,反而会降低系统的性能。这一点在多线程编程时应该注意。
Win32 SDK函数支持进行多线程的程序设计,并提供了操作系统原理中的各种同步、互斥和临界区等操作。Visual C++ 6.0中,使用MFC类库也实现了多线程的程序设计,线程被分为工作者线程(Worker Thread)和用户界面线程(User Interface Thread)两大类。前者常用于处理后台任务,执行这些后台任务并不会耽搁用户对应用程序的使用,即用户操作无需等待后台任务的完成。后者常用来独立的处理用户输入和相应用户的事件。其中用户界面线程的特点是拥有单独的消息队列,可以具有自己的窗口界面,能够对用户输入和事件做出响应。在应用程序中,根据用户界面线程具有消息队列这一特点,可以使之循环等待某一事件发生后再进行处理。由于Windows95时抢先式多任务的操作系统,即使一个线程因等待某事件而阻塞,其他线程仍然可以继续执行。
❷ java多线程的运行和平台相关吗,为什么
和平台无关, java程序可以跨平台运行,多线程的程序也是java程序没差别。
java如何跨平台参考:http://www.cnblogs.com/028fly/archive/2010/04/04/1704248.html
❸ 多线程调用方法问题
个人认为,你对线程理解有误,线程就是单一的线程,是执行任务(function)的平台.
Thread1平台上执行任务:func1()->func2()->func3()->......
Thread2平台上执行任务:func1()->func2()->func3()->......
你觉的会有什么错?只是他们在执行任务的时候可能会用到一些公共资源,可能会影响你任务的最终预想结果而已。
这样解释你明白了吗?
❹ java语言编写超市购物系统 运用多个类,多个监听,最好不要用数据库,用文件的形式
Java语言的主要特点:1.跨平台性所谓的跨平台性,是指软件可以不受计算机硬件和操作系统的约束而在任意计算机环境下正常运行。这是软件发展的趋势和编程人员追求的目标。之所以这样说,是因为计算机硬件的种类繁多,操作系统也各不相同,不同的用户和公司有自己不同的计算机环境偏好,而软件为了能在这些不同的环境里正常运行,就需要独立于这些平台。而在Java语言中,Java自带的虚拟机很好地实现了跨平台性。Java源程序代码经过编译后生成二进制的字节码是与平台无关的,但是可被Java虚拟机识别的一种机器码指令。Java虚拟机提供了一个字节码到底层硬件平台及操作系统的屏障,使得Java语言具备跨平台性。2.面向对象面向对象是指以对象为基本粒度,其下包含属性和方法。对象的说明用属性表达,而通过使用方法来操作这个对象。面向对象技术使得应用程序的开发变得简单易用,节省代码。Java是一种面向对象的语言,也继承了面向对象的诸多好处,如代码扩展、代码复用等。3.安全性安全性可以分为四个层面,即语言级安全性、编译时安全性、运行时安全性、可执行代码安全性。语言级安全性指Java的数据结构是完整的对象,这些封装过的数据类型具有安全性。编译时要进行Java语言和语义的检查,保证每个变量对应一个相应的值,编译后生成Java类。运行时Java类需要类加载器载入,并经由字节码校验器校验之后才可以运行。Java类在网络上使用时,对它的权限进行了设置,保证了被访问用户的安全性。4.多线程多线程在操作系统中已得到了最成功的应用。多线程是指允许一个应用程序同时存在两个或两个以上的线程,用于支持事务并发和多任务处理。Java除了内置的多线程技术之外,还定义了一些类、方法等来建立和管理用户定义的多线程。5.简单易用Java源代码的书写不拘泥于特定的环境,可以用记事本、文本编辑器等编辑软件来实现,然后将源文件进行编译,编译通过后可直接运行,通过调试则可得到想要的结果。
❺ java多线程的运行与平台相关吗
当然有关
多线程同步的实现方法不是完全通用,最主要的是不同平台下的效果存在差异
❻ 电商平台什么时候用多线程机制,具体是数据库连接吗还有哪些方式解决并发问题
数据库连接肯定是需要考虑多线程以及并发处理的。其他还有在web访问的时候多线程和并发的处理,你可以理解为对http请求的并发的处理。
❼ 请问购物车应用中 , 购物车Bean类里的方法为什么都加同步锁啊
同步锁那肯定用了像ArrayList之类的东西...
如果用Vector的话就不用了...
Vector采用队列式(Queue)存储方式,ArrayList可以内多线程同步读取容..
当多线程,如web每一个用户既一个线程,同时往Vector里存东西的时候,会把请求添加到队列中,一个一个按顺序存储.
而ArrayList被多个用户同时存储时,会一起往里放.会出现一些不可控制的异常.所以,为了保证只有一个用户使用ArrayList,所以需要线程同步.
❽ 如何让 windows 平台多线程 DLL 完整退出
如果你在windows平台开发动态链接库,并且在链接库启动了内部线程,那么你很有可能发现加载你的DLL的程序在退出时会死锁,有时候虽然主程序界面没有了,但是打开任务管理器,发现进程还在。
最近做播放器插件开发,基于directshow、vlc、mplayer框架,各做了一个插件,三个插件中都使用了另外一个媒体DLL库(Mylib.dll),并且都是通过动态加载(LoadLibrary)使用的。该DLL比较复杂,内部使用的线程;另外directshow、vlc的插件自身也是一个DLL,mplayer不支持动态插件,是内置源码编译。
在没有针对进程退出做处理时,三个播放器(基于directshow的播放器测试了GraphEidt、Windows Media Player)都不能正常退出。
通过查看线程调用栈,是在Mylib.dll最后卸载时,dll的一个全局对象析构中,等待一个事件(Event)对象不返回,而这个事件应该是另一个线程退出前设置为有信号,但是整个进程除了主线程外,其他线程都已经结束了,这说明线程是被强行结束了,主线程调用栈显示已经进入了_ExitProcess中,应该是在此之前主线程杀死了所有子线程。
三个播放器框架都没有找到退出通知的机制,所以能够想到的办法只有使用atexit,在程序结束时调用一个Mylib.dll停止接口(Mylib_Stop)。都是没有效果,仍然不能正常退出。
但是与上面的情形不一样的是,mplayer还是挂死在Mylib.dll中的全局对象析构中;directshow与vlc却直接挂死在Mylib_Stop函数中,调用栈显示正在等待另一个线程退出,但是这个线程却在_ExitThread的地方卡住了。
要解决全局对象析构中的死锁问题,需要让线程正常退出,而不是被强行终止,因此需要在_ExitProcess前面卸载Mylib.dll。我们把这个任务增加到atexit的过程中,因为atexit的函数在退出主函数main后就会被调用,修改之后,mplayer真的可以正常退出了。
对于directshow与vlc,都是在一个插件DLL中启动Mylib.dll,我们发现atexit注册的函数,是在插件Dll卸载的时候被调用,调用栈中有DllMain函数。联想到执行DllMain函数的一些细节,觉得情况应该是这样:系统在调用DllMain时会有一个全局锁,主线程已经进入DllMain,所有锁已经被加上,另一个线程退出时也会调用DllMain,也需要这个锁,这样就造成了主线程等待另一个线程退出,而这个线程又在等待主线程占有的锁,形成了死锁情形。
另外在DLL中使用atexit注册的函数,不像我们期望的那样在进程退出时调用,而且在相应的DLL卸载时调用,这一点MSDN没有说明,但是通过跟踪到atexit里面,发现确实是根据DLL还是EXE分别处理的,同时也发现EXE中使用的是_imp___onexit函数。
尝试用_imp___onexit替换atexit,编译没有问题,但是运行会crash,因为注册的退出执行函数的代码实际是在插件DLL,而这个DLL在进程退出前已经卸载,代码页面失效。
最终我们只能修改Mylib.dll,去除全局变量析构中的等待事件死锁,并且不使用atexit,这样能够适应三个播放器;代价是Mylib.dll没有正常终止,里面的线程被强行终止,有可能会有一些善后工作无法完成。
总结如下:1、带有内部线程DLL要想正常退出,需要导出一个退出函数接口,并且要求调用者在适当的时候调用。
2、要注意DLL中全局变量析构前,线程可能已经被强行终止,如果在析构中依赖某个线程完成一些工作,则要考虑这种可能性,但是直接等待线程句柄没有问题
3、在DLL代码中使用atexit注册的函数,不能期望在进程退出时被调用,另外不管是在DLL还是EXE代码中,不能将其他模块的函数注册到atexit中。
❾ java多线程开多少上限量。
“整式为单项式和多项式的统称,是有理式的一部分,在有理式中可以包含加,减,乘,除、乘方五种运算,但在整式中除数不能含有字母。
❿ 一个进程最多包含多少个线程
1,在x86平台32位系统,系统占用2GB地址空间,用户方式2GB。如果使用VS,链接程序开关/SACK 或者/F可以设置线程堆栈大小,默认分配一个线程的堆栈大小是1MB,当CreateThread参数的StackSize大小与链接程序设置的不一致时,采用的方法是谁大用谁的,所以用4KB修改当然不会有改变!理论上最大线程数=2GB/1MB=2048。
实际上这个用户方式的2GB并不会全部用作线程堆栈。首先程序的代码和数据、进程环境块、线程环境块、空指针区域等等也需要占用一定的地址空间;再者2GB只是虚拟内存,如果非分页内存被用完,就无法再创建线程,这个与特定机器有关,所以不同机器上做最大线程数测试得到的数字可能不一样。
2,操作系统给一个系统进程提供的空间是2GB ,而一个线程堆栈的空间默认在启动的时候是1MB 那么启动完2000后,基本上就有2GB了,你可以减小默认堆栈的大小。
3,默认情况下,一个线程的栈要预留1M的内存空间而一个进程中可用的内存空间只有2G,所以理论上一个进程中最多可以开2048个线程
但是内存当然不可能完全拿来作线程的栈,所以实际数目要比这个值要小。你也可以通过连接时修改默认栈大小,将其改的比较小,这样就可以多开一些线程。如将默认栈的大小改成512K,这样理论上最多就可以开4096个线程。即使物理内存再大,一个进程中可以起的线程总要受到2GB这个内存空间的限制。比方说你的机器装了64GB物理内存,但每个进程的内存空间还是4GB,其中用户态可用的还是2GB。如果是同一台机器内的话,能起多少线程也是受内存限制的。每个线程对象都要站用非页面内存,而非页面内存也是有限的,当非页面内存被耗尽时,也就无法创建线程了。
如果物理内存非常大,同一台机器内可以跑的线程数目的限制值会越来越大。
在Windows下写个程序,一个进程Fork出2000个左右线程就会异常退出了,为什么?
这个问题的产生是因为windows32位系统,一个进程所能使用的最大虚拟内存为2G,而一个线程的默认线程栈StackSize为1024K(1M),这样当线程数量逼近2000时,2000*1024K=2G(大约),内存资源就相当于耗尽。
4,默认每线程1MB堆栈的话,只能开2048线程(如果你的其它系统资源足够的话)。要想开更多线程,只能修改每个线程的堆栈,但实际中是不推荐这样做的,因为如果你的线程因为一些工作因为线程堆栈不够的话,会导致整个进程崩溃.修改堆栈的方法好像只在XP或以上系统有效,windows 2000中不支持。