专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Java教程 » JAVA教程:解析Java的多线程机制 »正文

JAVA教程:解析Java的多线程机制

来源: 发布时间:星期三, 2008年12月17日 浏览:2次 评论:0
、进程和应用区别      进程(Process)是最初定义在Unix等多用户、多任务操作系统环境下用于表示应用在内存环境中基本执行单元概念以Unix操作系统为例进程是Unix操作系统环境中基本成分、是系统资源分配基本单位Unix操作系统中完成几乎所有用户管理和资源分配等工作都是通过操作系统对应用进程控制来实现      C、C、Java等语言编写经相应编译器编译成可执行文件后提交给计算机处理器运行这时处在可执行状态中应用称为进程从用户角度来看进程是应用个执行过程从操作系统核心角度来看进程代表是操作系统分配内存、CPU时间片等资源基本单位是为正在运行提供运行环境进程和应用区别在于应用作为个静态文件存储在计算机系统硬盘等存储空间中而进程则是处于动态条件下由操作系统维护系统资源管理实体多任务环境下应用进程主要特点包括:      ●进程在执行过程中有内存单元入口点并且进程存活过程中始终拥有独立内存地址空间;      ●进程生存期状态包括创建、就绪、运行、阻塞和死亡等类型;      ●从应用进程在执行过程中向CPU发出运行指令形式区别可以将进程状态分为用户态和核心态处于用户态下进程执行是应用指令、处于核心态下应用进程执行是操作系统指令      在Unix操作系统启动过程中系统自动创建swapper、init等系统进程用于管理内存资源以及对用户进程进行调度等在Unix环境下无论是由操作系统创建进程还要由应用执行创建进程均拥有唯进程标识(PID) 2、进程和Java线程区别         应用在执行过程中存在个内存空间入口点地址、执行过程中代码执行序列以及用于标识进程结束内存出口点地址在进程执行过程中时间点均有唯处理器指令和内存单元地址相对应      Java语言中定义线程(Thread)同样包括个内存入口点地址、个出口点地址以及能够顺序执行代码序列但是进程和线程重要区别在于线程不能够单独执行它必须运行在处于活动状态应用进程中因此可以定义线程是内部具有并发性顺序代码流      Unix操作系统和Microsoft Windows操作系统支持多用户、多进程并发执行而Java语言支持应用进程内部多个执行线程并发执行多线程意义在于个应用多个逻辑单元可以并发地执行但是多线程并不意味着多个用户进程在执行操作系统也不把每个线程作为独立进程来分配独立系统资源进程可以创建其子进程子进程和父进程拥有区别可执行代码和数据内存空间而在用于代表应用进程中多个线程共享数据内存空间但保持每个线程拥有独立执行堆栈和执行上下文(Context)      基于上述区别线程也可以称为轻型进程 (Light Weight ProcessLWP)区别线程间允许任务协作和数据交换使得在计算机系统资源消耗等方面非常廉价      线程需要操作系统支持不是所有类型计算机都支持多线程应用Java设计语言将线程支持和语言运行环境结合在提供了多任务并发执行能力这就好比个人在处理家务过程中将衣服放到洗衣机中自动洗涤后将大米放在电饭锅里然后开始做菜等菜做好了饭熟了同时衣服也洗好了      需要注意是:在应用中使用多线程不会增加 CPU 数据处理能力只有在多CPU 计算机或者在网络计算体系结构下将Java划分为多个并发执行线程后同时启动多个线程运行使区别线程运行在基于区别处理器Java虚拟机中才能提高应用执行效率 另外如果应用必须等待网络连接或数据库连接等数据吞吐速度相对较慢资源时多线程应用是非常有利基于Internet应用有必要是多线程类型例如当开发要支持大量客户机服务器端应用可以将应用创建成多线程形式来响应客户端连接请求使每个连接用户独占个客户端连接线程这样用户感觉服务器只为连接用户自己服务从而缩短了服务器客户端响应时间       3、Java语言多线程设计思路方法         利用Java语言实现多线程应用思路方法很简单根据多线程应用继承或实现对象区别可以采用两种方式:种是应用并发运行对象直接继承Java线程类Thread;另外种方式是定义并发执行对象实现Runnable接口      继承Thread类多线程设计思路方法      Thread 类是JDK中定义用于控制线程对象在该类中封装了用于进行线程控制思路方法见下面举例代码:      [code]//Consumer.java   import java.util.*;    Consumer extends Thread   {    nTime;    String strConsumer;    public Consumer( nTime, String strConsumer)    {    this.nTime = nTime;    this.strConsumer = strConsumer;    }    public void run    {   while(true)   {    try   {    .out.prln("Consumer name:"+strConsumer+"\n");    Thread.sleep(nTime);    }   catch(Exception e)   {    e.prStackTrace;    }   }    }    public void (String args)   {    Consumer aConsumer = Consumer (1000, "aConsumer");    aConsumer.start;    Consumer bConsumer = Consumer (2000, "bConsumer");    bConsumer.start;    Consumer cConsumer = Consumer (3000, "cConsumer ");    cConsumer.start;   }   } [/code]               从上面代码可以看出:多线程执行地下Consumer继承Java语言中线程类Thread并且在思路方法中创建了 3个Consumer对象例子对象例子start思路方法时自动Consumer类中定义run思路方法启动对象线程运行线程运行结果是每间隔nTime时间打印出对象例子中串成员变量strConsumer内容      可以整理总结出继承Thread类多线程设计思路方法是使应用类继承Thread类并且在该类run思路方法中实现并发性处理过程      实现Runnable接口多线程设计思路方法      Java语言中提供另外种实现多线程应用思路方法是多线程对象实现Runnable接口并且在该类中定义用于启动线程run思路方法这种定义方式好处在于多线程应用对象可以继承其它对象而不是必须继承Thread类从而能够增加类定义逻辑性      实现Runnable接口多线程应用框架代码如下所示:      //Consumer.java   import java.util.*;    Consumer implements Runnable   {    … …   public Consumer( nTime, String strConsumer){… …}   public void run{… …}    public void (String args)   {   Thread aConsumer = Thread( Consumer(1000, "aConsumer"));   aConsumer.start;   //其它对象例子运行线程    //… …    }   }      从上述代码可以看出:该类实现了Runnable接口并且在该类中定义了run思路方法这种多线程应用实现方式和继承Thread类多线程应用重要区别在于启动多线程对象思路方法设计思路方法区别在上述代码中通过创建Thread对象例子并且将应用对象作为创建Thread类例子参数 4、线程间同步      Java应用多个线程共享同进程数据资源多个用户线程在并发运行过程中可能同时访问具有敏感性内容在Java中定义了线程同步概念实现对共享资源致性维护下面以笔者最近开发移动通信计费系统中线程间同步控制思路方法介绍说明Java语言中多线程同步方式实现过程      在没有多线程同步控制策略条件下客户账户类定义框架代码如下所示:      public RegisterAccount   {   float fBalance;   //客户缴费思路方法   public void deposit(float fFees){ fBalance fFees; }   //通话计费思路方法   public void withdraw(float fFees){ fBalance -= fFees; }   … …   }               读者也许会认为:上述代码完全能够满足计费系统实际需要确实在单线程环境下该确实是可靠但是多进程并发运行情况是怎样呢?假设发生这种情况:客户在客户服务中心进行缴费同时正在利用移动通信设备仅此通话客户通话结束时计费系统启动计费进程而同时服务中心工作人员也提交缴费进程运行读者可以看到如果发生这种情况对客户账户处理是不严肃      如何解决这种问题呢?很简单在RegisterAccount类思路方法定义中加上用于标识同步思路方法关键字synchronized这样在同步思路方法执行过程中该思路方法涉及共享资源(在上述代码中为fBalance成员变量)将被加上共享锁以确保在思路方法运行期间只有该思路方法能够对共享资源进行访问直到该思路方法线程运行结束打开共享锁其它线程才能够访问这些共享资源在共享锁没有打开时候其它访问共享资源线程处于阻塞状态      进行线程同步策略控制后RegisterAccount类定义如下面代码所示:      public RegisterAccount   {   float fBalance;   public synchronized void deposit(float fFees){ fBalance fFees; }   public synchronized void withdraw(float fFees){ fBalance -= fFees; }   … …   }      从经过线程同步机制定义后代码形式可以看出:在对共享资源进行访问思路方法访问属性关键字(public)后附加同步定义关键字synchronized使得同步思路方法在对共享资源访问时候为这些敏感资源附加共享锁来控制思路方法执行期间资源独占性实现了应用系统数据资源致性管理和维护 5、 Java线程管理         线程状态控制      在这里需要明确是:无论采用继承Thread类还是实现Runnable接口来实现应用多线程能力都需要在该类中定义用于完成实际功能run思路方法这个run思路方法称为线程体(Thread Body)按照线程体在计算机系统内存中状态区别可以将线程分为创建、就绪、运行、睡眠、挂起和死亡等类型这些线程状态类型下线程特征为:      创建状态:当利用关键字创建线程对象例子后它仅仅作为个对象例子存在JVM没有为其分配CPU时间片等线程运行资源;      就绪状态:在处于创建状态线程中start思路方法将线程状态转换为就绪状态这时线程已经得到除CPU时间的外其它系统资源只等JVM线程调度器按照线程优先级对该线程进行调度从而使该线程拥有能够获得CPU时间片机会      睡眠状态:在线程运行过程中可以sleep思路方法并在思路方法参数中指定线程睡眠时间将线程状态转换为睡眠状态这时该线程在不释放占用资源情况下停止运行指定睡眠时间时间到达后线程重新由JVM线程调度器进行调度和管理      挂起状态:可以通过suspend思路方法将线程状态转换为挂起状态这时线程将释放占用所有资源由JVM调度转入临时存储空间直至应用resume思路方法恢复线程运行      死亡状态:当线程体运行结束或者线程对象stop思路方法后线程将终止运行由JVM收回线程占用资源      在Java线程类中分别定义了相应思路方法用于在应用中对线程状态进行控制和管理      线程调度      线程意义在于JVM应对运行多个线程进行系统级协调以避免多个线程争用有限资源而导致应用系统死机或者崩溃      为了线程对于操作系统和用户重要性区分开Java定义了线程优先级策略Java将线程优先级分为10个等级分别用1-10的间数字表示数字越大表明线程级别越高相应地在Thread类中定义了表示线程最低、最高和普通优先级成员变量MIN_PRIORITY、MAX_PRIORITY和NORMAL_PRIORITY代表优先级等级分别为1、10和5个线程对象被创建时其默认线程优先级是5      为了控制线程运行策略Java定义了线程调度器来监控系统中处于就绪状态所有线程线程调度器按照线程优先级决定那个线程投入处理器运行在多个线程处于就绪状态条件下具有高优先级线程会在低优先级线程的前得到执行线程调度器同样采用"抢占式"策略来调度线程执行即当前线程执行过程中有较高优先级线程进入就绪状态则高优先级线程立即被调度执行具有相同优先级所有线程采用轮转方式来共同分配CPU时间片      在应用中设置线程优先级思路方法很简单在创建线程对象的后可以线程对象Priority思路方法改变该线程运行优先级同样可以getPriority思路方法获取当前线程优先级      在Java中比较特殊线程是被称为守护(Daemon)线程低级别线程这个线程具有最低优先级用于为系统中其它对象和线程提供服务个用户线程设置为守护线程方式是在线程对象创建的前线程对象Daemon思路方法典型守护线程例子是JVM中系统资源自动回收线程它始终在低级别状态中运行用于实时监控和管理系统中可回收资源      线程分组管理      Java定义了在多线程运行系统中线程组(ThreadGroup)对象用于实现按照特定功能对线程进行集中式分组管理用户创建每个线程均属于某线程组这个线程组可以在线程创建时指定也可以不指定线程组以使该线程处于默认线程组的中但是旦线程加入某线程组该线程就直存在于该线程组中直至线程死亡不能在中途改变线程所属线程组      当JavaApplication应用运行时JVM创建名称为线程组除非单独指定在该应用中创建线程均属于线程组线程组中可以创建其它名称线程组并将其它线程加入到该线程组中依此类推构成线程和线程组的间树型管理和继承关系      和线程类似可以针对线程组对象进行线程组调度、状态管理以及优先级设置等在对线程组进行管理过程中加入到某线程组中所有线程均被看作统对象 6、小结: 本文针对Java平台中线程性质和应用多线程策略进行了分析和讲解      和其它操作系统环境区别Java运行环境中线程类似于多用户、多任务操作系统环境下进程但在进程和线程运行及创建方式等方面进程和Java线程具有明显区别      Unix操作系统环境下应用可以利用fork创建子进程但子进程和该应用进程拥有独立地址空间、系统资源和代码执行单元并且进程调度是由操作系统来完成使得在应用进程的间进行通信和线程协调相对复杂而Java应用多线程则是共享同应用系统资源多个并行代码执行体线程的间通信和协调思路方法相对简单      可以说:Java语言对应用多线程能力支持增强了Java作为网络设计语言优势为实现分布式应用系统中多客户端并发访问以及提高服务器响应效率奠定坚实基础
标签:

相关文章

读者评论

  • 共0条 分0页

发表评论

  • 昵称:
  • 内容: