java多线程异步并行-c#同步线程和异步线程
利用Java的多线程技术实现并行多任务管理网澜湄; 智慧密集型多线程在编程社会是一个相当新的结构,而且非常强大。 可以提高程序的运行效率。 Java 虚拟机允许一个应用程序同时运行多个线程。 j'a 编程环境和 Rumime 库最关键的特性之一就是多线程结构,而 Java 是第一个在语言核心支持线程的收缩语言。 使用多线程收缩技术。 Java可以很容易地实现任务的并行处理。 限于篇幅,本文不深入讨论Java中线程相关的类和接口的构造函数和方法。 演示程序中的所有代码都有详细说明。 注、线程(Thread)基础知识 所谓线程,就是一个进程中的一个简单的运行流程。 进程是在它自己的地址空间中执行的程序。 线程是在进程上下文中运行的代码序列。 事实上,线程不能在自己的地址空间中执行。 他们需要先运行一个父进程。 正如我们所提到的,机器上运行的每个进程无疑都是由一些正在运行的线程组成的,但是,线程总是与特定的进程相关联。每个线程都有一个优先级。 在3ava中,默认线程优先级为5(即NORMPRIOPdTY),最高优先级为10(即:MAX_pRIORITY),最低优先级为1(即{MIN~t´RIORITY)。
优先级高的线程先执行,优先级低的线程后执行。 线程可以设置为守护线程(daenmn)。 当线程中运行的代码创建一个新的线程对象时,新线程拥有和创建它的线程相同的优先级。 二、线程的状态线程的行为完全依赖于线程的状态。 线程有以下四种状态。 1New 当线程被创建并且还没有调用start方法时,线程处于“n”状态。 2、对于新创建的线程,在调用start方法后,会自动调用m方法,线程进入“Ible”状态。此时我们可以认为线程正在运行,因为rum的执行方法意味着线程正在运行。 但是,我们应该考虑线程的优先级。 对于CPU来说,一次只能运行一个线程,虽然这样java多线程异步并行,我们仍然认为它处于“rankle”状态,因为所有线程都在共享系统资源。 3NotRunning 由于某些原因,一些线程会暂时挂起,然后进入“notrunning”状态。 处于这种状态的线程仍然与用户相关,并且仍然可以重新进入“可运行”状态。 在Java中,以下这些事件会导致线程暂时挂起:调用deep方法; 调用等待方法; 线程由于 I10 (bxo~) 而被阻塞。 以下事件会导致处于“notrunning”状态的线程重新进入“nine lnhue”状态: if 线程休眠,并且sleep方法指定的时间已经过去; 如果线程正在等待,则带有条件变量的对象调用notify或nofifyA1]方法; 如果线程由于 I/0 而阻塞,则 I/0 操作已完成。
4.死线程如果不再需要线程,则进入“ead”状态,死线程不能再被恢复执行。 线程进入“死亡”状态。 e血方法有两种调用方式,安全管理器允许执行退出操作。 All threads Neither 不是守护线程并且已经死亡,或者从调用 rum 方法返回,或者在 run 方法中抛出异常。 三、线程相关的类。 Java 编程语言通过一个接口和几个类提供对线程的支持。 这些接口和类分别是bunna~e、class、threaddeath、threadc、group和class。 所有这些类都是 java isng 包的一部分。 b]e接口Java不直接支持多重继承,即从多个父类派生一个类。 如果一个类是从其他类派生出来的,它可以使用 Rummble 接口使其支持线程。 实用的第一组智慧是 rh~ad 类最负责为其他类提供线程函数。 主类,以便向类添加线程功能。 我们可以简单地从 1hre 类派生一个类。 并重载 nln 方法。 nln 方法是线程发生的地方。 它通常被称为线程体。 必须注意的是,Tlmead类中没有使用stop和suspend1-esunm方法(deprecation),主要原因是这些方法不安全,容易死镇。 3Thread1) eathThmadDeath类提供了错误机制。
允许我们清理异步中断的线程。 我们称它为错误类,因为它是从 Error 类派生的。 ThreadGroup 类通常用于管理一组线程。 线程组代表一组线程。 一个线程组还可以包含其他线程组。 线程组只允许组内的线程访问有关线程组的信息。 5、ObjeciObject类虽然不是严格的线程支持类,但它提供了三个方法,这三个方法对Java线程结构至关重要。 这些方法是 wait、notify 和 110ti Bai Al]。 wmt 方法使线程在休眠状态下等待。 它一直持续到通知为止; 同样,notify方法通知等待线程继续执行; notify/ill 方法与nol bamboo 相同,但它会通知所有等待的线程。 这三个方法只能被syncronized方法调用。 第四,开发大型软件项目时创建线程。 通过将任务划分到不同的线程中并行运行,可以充分利用系统资源。 提高程序的运行效率。 这也是使用线程的根本目的。 因此,我们可以独立地将需要以线程方式执行的函数放在13x~esd类的派生类中,或者放在run()方法中。 并行执行。 在 Java 中,有两种创建线程的方法。 1ExtendThread 如果我们的类不需要从其他类派生,可以直接从Thread类派生,例如:publicclassThreadMeextendsThread,需要以线程模式运行的代码很简单,为了实际使用和设置线程在程序中的行为,我们可以简单地创建一个对象并调用nln方法,例如:ThreadMeme = newThreadMe()。
Fnestart1]。 qiu方法自动调用mn方法进行线程的具体处理。 该线程将一直运行,直到它退出 mn 方法。 2. ImplementRunnable 如果我们的类需要派生自其他类而不是1hre类,由于Java不允许类的多重继承,此时。 只能使用 Runnable 端口。 类中实现Runnable接口的方法如下: publicclassThreadYouextendsApptimplementsRunnable//线程模式下需要运行的代码有两种启动线程的方式:Th~adYeuyou=newThreadYouc), Threadt=newThread(you) tstartc]: or: ThreadYouyou=newThreadYou( }.newThread(you)startc): 五、多线程组管理 多线程编程是很多程序员头疼的事情,尤其是有很多线程同时运行的时候,管理这些threads 是一个相当大的任务 在 Java 中,困难的事情是提供 Thread Groups (j stare a1 and IIg。Thres~Group 有时对线程分组非常有用,它允许我们将多个线程作为一个实体来控制。在大多数应用程序中,线程可以根据实际情况分为不同的组,Pamtlme系统中的每个线程都属于一个线程组,如果我们在创建线程的时候没有指定线程组,那么这个线程就被加入到线程g中当前线程所属的组,当前线程就是创建新线程的线程。
我们将线程与线程组相关联。 我们只是在创建线程的时候指定了它属于哪个线程组,之后就不能更改了。 在创建线程之前,我们可以先创建一个ThreadGroup对象。 下面的代码创建了一个名为TluzadGroup02的线程组upD2,并在其中添加了线程类Tmnmaction()实现的两个线程~ansactionO1和tzansactlon02。 这两个线程的线程名称分别是TmsaedmO1和Transaction02。 ThreadGroupgroup02=newThreadGroup(Thread—Groupo2》:Threadtransaction01=newThread(group02.newTmns-action(]Transaction01).Threadtransaction02=newThread{group02.newTrans—action{),Transactlon02)。 事务 01 开始{)。 transaction02startl1 创建线程组后,创建每个线程并传递给'131ureadG~对象成为线程组的成员,每个线程都可以调用start方法启动。 TlueadGroup 类不提供一次启动所有线程的方法。
与Tlxiud类一样,不鼓励使用TIIIeadcr咖啡IP方法(dePrecol1),因此建议调整优先级,让线程休眠(s]eep),实现线程组的挂起或运行操作。 六、并行处理的概念并行处理(countP Fan Zhao iIlg)是指由以下三组同时执行多个程序的能力。 其作用是充分利用高速中央处理器: 2、利用部分硬件交错分时工作java多线程异步并行,同时处理两个以上的独立任务; 3、计算机在内存中同时存储两个或多个程序,并进行分时控制,使这些程序并行执行。 对于多处理器计算机,Java虚拟机将所有的CPU作为一个池,这样当一个用Java编写的具有并行处理能力的程序提交给Java虚拟机执行时,程序中的线程不会面临单一的CPU。 CPU,而是 CPU 池中的所有 CPU。 显然,此时多任务的并行处理能力将得到显着提升。 七、MthreadDemo的例子。 javit演示了如何利用Java的多线程技术开发多任务并行处理程序。 假设MthreadDemo。 Java运行在服务器上,并行处理时不考虑时间敏感数据的同步。 在程序中,我定义了两个线程类,分别代表完成两个不同的任务,假设QIIerjr类实现了数据库的查询功能,On-6on类进行实时业务交易。
在实际应用中。 经常会出现同一类型任务的多个请求同时到达,比如同时有多个查询请求和多个事务请求。 为了响应这些请求,必须及时合理地创建多个线程。 在程序中,我们假设有3个查询线程和2个事务线程同时运行,它们同时运行,共享系统资源。 对于处理相同类型任务的线程。 它们可以集中放入一个线程组中进行集中处理和样本选择。 一类任务对应一个线程组。 根据任务的重要性和对响应时间的要求,可以分别设置不同的线程组。 优先事项。 程序中我们将事务线程放在线程组up02中,查询线程放在线程组1中,02的优先级高于group01。 样本选择、线程管理变得简单多了。 另外,同一个线程组中处理同类型任务的线程即使有不同的优先级上限也不能独占系统资源(比如CPU)。 必须轮流执行,共享系统资源。 在程序中。 我们使用 sleep() 方法来模拟这种情况,让同一线程组中的线程轮流休眠一个随机的毫秒数。 M线程演示。 jave的完整源程序如下。 对于事务线程,在~oupO2线程组中,线程开始运行前两次不休眠,独占系统资源一段时间。
classMThreadDemo staticpublic voidmain(String[1args) //创建一个新的线程组group01,命名为ThreadGroup01 ThreadGroupgroup01=newThreadGroupfThread-Group01): group01setMa~Pdority(4I: //创建一个新的线程,并将其加入线程组group01 Threadquery01=newThreadfgroup01, newQueryc1Query01I : Threadquery02=newThreadcgroup01,newQuery(), Query02J: Threadquery03=newThread(group01.newQuery(), Query03), //新建线程组groupO2,命名为ThreadGroup02 ThreadGroupgroup02=newThreadGroup(Thread—Group02): //新建线程并加入线程组group02 Threadtransaction01=newThread(group02newTransactionTransaction01): Th~adtransaction02=nevvThreadfgroup02new Transactionc)TransacOn02J: //将当前所有线程组的SystemOut信息输出到屏幕上。
打印(=========)。 SVstemOUT。 pdntlnI The threads in thread group group01 are: group01list【l://Display all threads in thread group group01 SystemoutpdnUnf Threads in thread group group02 are:: group02list【】//显示培城组group01中的所有线程 Systemoutprintlnc =:= ======): query01startc),//启动线程 query02startc): query03start(): transaction01startI) transaction02start(): trv 实战第一志朋合集 //睡眠随机数毫秒 ThreadcurrentThread【Jsteep{ fint)fMath . random 1O0}): lcatchcInterruptedExceptionelII//显示当前线程的信息Systemoutprintln{ThreadcurrentThread(}4-running.次数为:4-cntJ:ifIcnt)2)//休眠一个机器ThreadcurrentThreadc)的毫秒数睡眠((int]cMath。
randomc}} 100}): catchfInterruptedExceptiona}i]//显示具体的当前信息 Systemoutprintln(ThreadcurrentThread{)+run. 次数为:4-cnt)。 MIHDDEM。 jm 在Windows98/NT 中使用JDK1.3 编译。 在命令行运行的命令为:e:\jdkl3\bin\javaMThreadDemo 建议读者多运行几次,你会发现每次运行的结果都差不多。 这是由于让线程休眠十个随机毫秒造成的。 下面是某个操作的结果:线程组Stoup01中的线程是:jm。 ITlweadGroup[name=ThreadG~mpO1,m ThIead【Q. ~701,4,ThreadGroup01] 1 [QI. ey eyeing, 4. 1G delete po1] 1 [QI_ery03, 4, TleeadGroup01] jB. 1 昂。 “rm~adGvoup[name=~Group02,mx=lO]~[Transactlon01.5,ThreadG~up02]Tluead[TmnsactionO2,5,1adGmp.2] 块 nB0IIo1。
5、nl跳p02l运行,第二个是:I 11~。 d[TlB|cd0IIoI。 5、nl[Ttaneact/on02]运行,第二个操作是:2~[Ttaneact/on02. 5、G[on02]运行,第二次运行是:I[1”h~tion02.5,1G姐lp02]运行,次数是:2Tleead[Transsctlon02,5,1G姐lp02]运行,次数为:3 1 [ry03,4´Gr [帅由n0I,5.TeadG姐lp02J运行,次数为:3 ~[QuetT01,4,TleeadGreup01]运行。第二个为:I Thread [ Tramaction01, 5. Grmlp02] 运行,第二个是:4 ´lllead [TmneaetJe~12, 5, Gr called P02] 运行,第二个是:4 1 [Quel2´4, ThreadG~ up01] 运行,次数:2 1fQ1.day y.4, Th-~IGroupO1] running, times: 2 1 [QII, o3.4, ThresdGroup01] running, times: 3 Tied[~03.4 , ThresdGroup01] runs, 次数为: 4 Thread [ QI. eryol, 4´ThresdGmup01] 运行,次数为:2 Thread [Ttanesetlon02,5, GloI_02] 运行,次数为:5 ships dfn cypress crucian carp exports n0l, 5, n female ad 1【Ql 】q02,4´岛。
IIp0l]运行,次数为:3[Ql]q02,4´岛。 IIp0l] 运行,次数为:4 [shirt ry03,4´Gr is called pol] 运行,次数为:5 ~[QuetT01,4. Gr叫pol]跑,二控是:3[Qe,2´4Gr 1[QI. eryol,4。 ~Gtoup01] 运行,第二个集合为:41 [lerl, 4. ~Gtoup01] 运行,时间为:5 输出结果中,线程T´mead[Transaction01, 5, IC, ~p02 ] 为:Tntu~tion01为当前运行线程,5为上一个运行线程(Thu canthus maggot的首选后缀01),TlueadC。 roup02 是当前正在运行的线程(Tn,msecgon01)的线程组。 其他线程类似。 我们可以看到,由于线程组ThresdGroup01的优先级为4,低于优先级为5的线程组111r和Gr0lpD2,因此虽然query01、~ery02和qu~03先启动。 但是Thre~0~p02中的线程Tra~setion01和Tracmcti~02先运行,从第二个周期开始,让线程在程序中休眠十个随机毫秒,这样当IdG_1D2中的线程休眠时,~运行 mupO1 过程(query01、query02 和 query03)。
Thrmd-Group02中的线程休眠时间一到,就会先运行。 ThIad-C,o。 pO1 中的线程进入。 不是状态。 另外,由于线程组Thr~dGzoep02的优先级高于ThIead-C,o。 p01 的高点。 虽然每次操作的结果不同,但每次操作ThIead-C,o。 p02 中的线程总是先结束运行。 (收到日期:2000 年 10 月 24 日