浅析Java多线程机制

来源 :电脑知识与技术·学术交流 | 被引量 : 0次 | 上传用户:longzhi2009
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  摘要:本文在对Java多线程分析的基础上,针对如何实现多线程,如何进行同步,如何管理多线程等问题进行了简单的阐述。
  关键词:线程;多线程;线程组
  中图分类号:TP311文献标识码:A文章编号:1009-3044(2008)19-30181-03
  Analyse Shallowly Java Multi-threading Mechanism
  WANG Jun-yu, WANG Xian-hong
  (Sanmenxia Vocational and Technical College, Sanmenxia 472000, China)
  Abstract: This text is based on the analysis of Java multi-threading mechanism, aim at how to carry out a multi-threading, how to carry on synchronously, how to manage multi-threading’s etc.’s problem to carry on to expound in brief.
  Key words: thread; multi-threading; thread group
  
  1 理解多线程
  
  传统的程序大多是单线程的,即一个程序只有一条从头至尾的执行线索。然而现实世界中的很多过程都具有多条线索同时动作的特性。例如:我们可以一边看书,一边摆动胳膊,如果不容许这样做,我们会感觉很难受。再如一个网络服务器可能需要同时处理多个客户机的请求等。
  Java语言的一大特性就是内置对多线程的支持。多线程是这样的一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。
  多个线程是并发执行的,也就是在逻辑上“同时”,而不管是否是物理上的“同时”。若系统只有一个CPU,真正的“同时”是不可能的,但是由于CPU的速度非常快,用户感觉不到其中的区别,因此我们也不用关心它,只需要设想各个线程是同时执行的即可。多线程和传统的单线程在程序设计上最大的区别在于,由于各个线程的控制流彼此独立,为了建立这些线程正在同步执行的感觉,Java快速地把控制从一个线程切换到另一个线程。
  
  2 线程与程序、进程的区别
  
  程序是一段静态的代码,它是应用软件执行的蓝本。
  进程是程序的一次动态执行过程,它对应了从代码加载、执行至执行完毕的一个完整过程,这个过程也是进程本身从产生、发展至消亡的过程。如果把银行一天的工作比作一个进程,那么早上打铃上班是进程的开始,晚上打下班铃是进程的结束。
  线程是比进程更小的执行单位。尽管线程在一些程序语言中又称为进程,但是基本的思想是相同的:一个线程是一个运行在后台的、独立于主应用程序的任务[2]。所有的程序至少自动拥有一个线程。这个线程称为主线程,当程序加载到内存中时,启动主线程。要加载第二个、第三个或者第四个线程,程序就要使用Thread类和Runnable接口。
  
  3 在Java中实现多线程
  
  在Java中实现多线程有两个途径:继承Thread类和实现Runnable接口。
  3.1 继承Thread类的多线程程序设计方法
  Thread 类是JDK中定义的用于控制线程对象的类,在该类中封装了用于进行线程控制的方法。见下面的示例代码:
  import java.util.*;
  class TimePrinter extends Thread {
  int pauseTime;
  String name;
  public TimePrinter(int x, String n) {
  pauseTime = x;
  name = n;
  }
  public void run() {
  while(true) {
  try {
  System.out.println(name ":" new
  Date(System.currentTimeMillis()));
  Thread.sleep(pauseTime);
  } catch(Exception e) {
  System.out.println(e);}}}
  static public void main(String args[]) {
  TimePrinter tp1 = new TimePrinter(1000, "Fast Guy");
  tp1.start();
  TimePrinter tp2 = new TimePrinter(3000, "Slow Guy");
  tp2.start();}}
  这种方法简单明了,符合我们的习惯,但它有一个很大的缺点,那就是如果我们创建的类已经从一个类继承(如小程序必须继承自 Applet 类),那么无法再继承 Thread 类,而这时我们又不想建立一个新的类,怎么办呢?我们可以这样做:就是不创建 Thread 类的子类,而是直接使用它,若直接使用Thread类,那就需要Runnable接口支持。虽然抽象类也可满足,但需要继承,为了避免继承带来的限制,则只有使用Java 提供的接口 java.lang.Runnable 来支持。
  3.2 实现Runnable接口的多线程程序设计方法
  Java语言中提供的另外一种实现多线程应用程序的方法是多线程对象实现Runnable接口并且在该类中定义用于启动线程的run方法。这种定义方式的好处在于多线程应用对象可以继承其它对象而不是必须继承Thread类,从而能够增加类定义的逻辑性。实现Runnable接口的多线程应用程序如下所示:
  public class MyThread implements Runnable {
  int count= 1, number;
  public MyThread(int num) {
  number = num;
  System.out.println("创建线程 " number);
  }
  public void run() {
  while(true) {
  System.out.println("线程 " number ":计数 " count);
  if( count== 6) return;
  } }
  public static void main(String args[]) {
  for(int i = 0; i < 5; i ) new Thread(new MyThread(i 1)).start();}}
  使用 Runnable 接口来实现多线程使得我们能够在一个类中包容所有的代码,有利于封装,它的缺点在于,我们只能使用一套代码,若想创建多个线程并使各个线程执行不同的代码,则仍必须额外创建类,如果这样的话,在大多数情况下也许还不如直接用多个类分别继承 Thread 来得紧凑。这两种方法,各有千秋,可灵活使用。
  
  4 线程间的同步
  
  由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。比如一个工资管理负责人正在修改雇员的工资表,而一些雇员也正在领取工资,如果容许这样做必然出现混乱。因此工资管理负责人正在修改工资表时(包括他喝茶休息一会),将不容许任何雇员领取工资,也就是说这些雇员必须等待。如在没有多线程同步控制策略条件下的代码:
  public class SharedResouce {
  private int a = 0;
  private int b = 0;
  public void setA(int a) { this.a = a; }
  public void setB(int b) { this.b = b; }
  }
  由于未加锁setA()时,可以setB(),setB()时可以setA()。这时两个以上的线程同时执行,会引发冲突。因此在Java中定义了线程同步的概念,用synchronized关键字为共享资源加锁来解决同步的问题,实现对共享资源的一致性维护。进行线程同步策略控制后的程序代码如下所示:
  public class SharedResouce {
  private int a = 0;
  private int b = 0;
  public void synchronized setA(int a) { this.a = a; }
  public void synchronized setB(int b) { this.b = b; }
  }
  同步整个方法,则setA()的时候无法setB(),setB()时无法setA()。也就是说,在任何一个时刻只能有一个线程访问setA()或者setB()。
  
  5 Java线程的管理
  
  5.1 线程的状态控制
  要想实现多线程,必须在主线程中创建新的线程对象,新建的线程对象在它的一个完整的生命周期中通常要经历5种状态。在控制线程从一种状态转入另一种状态时,必须调用正确的方法,如果调用的方法错误,就会产生一些异常[1]。5种状态如下:
  新建状态:当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态。此时它已经有了相应的内存空间和其他资源。
  就绪状态:在处于新建状态的线程中调用start方法将线程的状态转换为就绪状态。这时,线程已经得到除CPU时间之外的其它系统资源,只等JVM的线程调度器按照线程的优先级对该线程进行调度,从而使该线程拥有能够获得CPU时间片的机会。
  运行状态:当就绪的线程被调度并获得处理器资源时,便进入运行状态。
  阻塞状态:一个正在运行的线程因某种原因不能继续运行时,进入阻塞状态。
  死亡状态:处于死亡状态的线程不具有继续运行的能力。线程死亡的原因有二,一个是正常运行的线程完成了它的全部工作,即执行完了run()方法的最后一个语句并退出,另一个是线程被提前强制性的终止。
  5.2 线程的调度
  线程调用的意义在于JVM应对运行的多个线程进行系统级的协调,以避免多个线程争用有限资源而导致应用系统死机或者崩溃。
  处于就绪状态的线程首先进入就绪队列排队处理器资源,同一时刻在就绪队列中的线程可能有多个。多线程系统会给每个线程自动分配一个线程的优先级,任务较紧急的重要线程,其优先级就较高;相反则较低。在线程排队时,优先级高的线程可以排在较前的位置,能优先享用到处理器资源,而优先级较低的线程则只能等到排在它前面的高优先级线程执行完毕之后才能获得处理器资源。对于优先级相同的线程,则遵循队列的“先进先出”的原则,即先进入就绪状态排队的线程被优先分配到处理器资源,随后才后进入队列的线程服务。
  当一个在就绪队列中排队的线程被分配到处理器资源而进入运行状态之后,这个线程就称为是被“调度”或被线程调度管理器选中了。线程调度管理器负责管理线程排队和处理器在线程间的分配,一般都配有一个精心设计的线程调度算法。在Java系统中,线程调度依据优先级基础上的“先到先服务”的原则。
  5.3 线程分组管理
  Java定义了在多线程运行系统中的线程组(ThreadGroup)对象,用于实现按照特定功能对线程进行集中式分组管理。用户创建的每个线程均属于某线程组,这个线程组可以在线程创建时指定,也可以不指定线程组以使该线程处于默认的线程组之中。但是,一旦线程加入某线程组,该线程就一直存在于该线程组中直至线程死亡,不能在中途改变线程所属的线程组。
  当Java的Application应用程序运行时,JVM创建名称为main的线程组。除非单独指定,在该应用程序中创建的线程均属于main线程组。在main线程组中可以创建其它名称的线程组并将其它线程加入到该线程组中,依此类推,构成线程和线程组之间的树型管理和继承关系。与线程类似,可以针对线程组对象进行线程组的调度、状态管理以及优先级设置等。在对线程组进行管理过程中,加入到某线程组中的所有线程均被看作统一的对象。
  
  6 小结
  Java语言对应用程序多线程能力的支持增强了Java作为网络程序设计语言的优势,为实现分布式应用系统中多客户端的并发访问以及提高服务器的响应效率奠定坚实基础。
  
  参考文献:
  [1] 陈强, 孙建华, 等.Java程序设计[M].北京:人民邮电出版社,2001.12:125-137.
  [2] (美)布雷恩·奥弗兰,迈克尔·莫里森 著;刘伟,朱诗兵, 等译. Java2精要.语言详解与编程指南[M].北京:清华大学出版社,2002.9.
其他文献
摘要:介绍什么是P2P以及在局域网中的危害,如何封堵P2P。  关键词:P2P  中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)09-11638-02    How to Block P2P in LAN Network  WANG Tao  (Library in Mufu of Jinling Institute of Technology, Nanjing 21
2018年2月6日,四川省文联七届三次全委会在成都新华宾馆武担楼三楼雪域厅成功召开。四川省文联主席郑晓幸,四川省文联党组书记、常务副主席平志英,四川省文联党组副书记、副主席兼秘书长李兵,四川省文联党组副书记刘建刚,以及省文联主席团成员,全委会委员代表140余人出席会议,省委宣传部文艺处有关同志列席大会。  上午,四川省文联主席郑晓幸主持会议。会议第一议程传达中国文联党组书记、副主席、书记处书记李屹
摘要:网络化视频监视是远程视频监控、远程视频会议等应用的基础,采用Microsoft提供的VFW技术,获取摄像头视频信号,通过C/S模式通信编程,实现网络化视频监视功能。该程序可以使用于集中视频监视、远程视频会话等场合,具有应用范围广、通用性强、编程相对简单、成本低、可靠性高等优势。  关键词:网络化;视频;监视  中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)09-
摘要:汉语国际教育专业人才培养的主要目标是培养国际汉语教学合格师资,专业教学实习是人才培养的重要环节。通过专业教学实习,尤其是境外教学实习,让学生实现理论基础知识 实践能力培养、第二语言应用能力、国际意识和跨文化交际能力、涉外项目的设计、组织、实施等多种能力的培养。  关键词:汉语国际教育 境外教学实习(IAP) 国际汉语教师培养  一、汉语国际教育专业教学实习的重要性  汉语国际教育专业人才培养
我国汉语言文学源远流长,博大精深,其中潜藏着无限的奥秘,值得我们不断探索。汉语言文学作为大学阶段的教育内容,有利于提高大学生的文化素养、认知水平以及审美能力。在职业教育中开设汉语言文学知识课同样有着重要的价值和意义,尤其是与历史文化密切相关的旅游行业的教育培训,提升从业人员的专业素养和文化底蕴既是行业的基本要求,也是新时代下市场的内在需求。由韩荔华编写的《汉语言文学知识》一书正是一本适合导游专业人
儿童诗是指结合儿童生长发育特点和心理特点,为提高儿童阅读欣赏能力,专门为儿童创作的诗歌。儿童诗展现了儿童丰富的内心世界,把儿童独有的内心世界和情绪活动生动地传达出来,情趣盎然,是一种陶冶儿童情操、发散儿童思维、发展儿童语言的非常好的素材。统编教材低年级段中有很多儿童诗,诗中有优美的语言、丰富的想象、新奇的构思,从中儿童可以获得美的体验与快乐。  《义务教育语文课程标准(2011年版)》(以下简称“
[摘要]诗歌是中国传统文化中重要的一部分,在曹雪芹先生的代表作品《红楼梦》中,诗歌也有所体现。由于《红楼梦》在文学史上的重要地位,很多人都对其进行了英译,在这些英译本中,杨宪益夫妇以及大卫·霍克斯的译本较为突出。本文就这两个译本从信息功能,美学功能,文化传递功能等方面进行对比分析,以期通过对译本的研究进一步促进中国文化走向世界。  [关键词]《红楼梦》;诗歌翻译;信息功能;美学功能;文化传递功能 
摘要:随着计算机网络的普及,网络教学愈来愈受到教育者的重视。该文主要讨论计算机导论课程的网络教学平台的设计,详细分析该系统的系统结构和功能,论述系统中主要功能模块的实现。  关键词:网络教学;B/S模式;学习系统;练习与测试;演示动画  中图分类号:TP315文献标识码:A文章编号:1009-3044(2008)33-1433-02  Design and Realization of Netwo
摘要:在Intel未来教育的先进理念的指引下,从基于局域网的网络课件的特征与内涵出发,以建构主义与“双主模式”教学理论为指导,利用局域网与互联网的优势,介绍设计开发新型网络课件的方法,并结合实际教学过程中的具体例子,提出相应的解决策略。  关键词:Intel未来教育;双主模式;网络课件   中图分类号:TP311文献标识码:A文章编号:1009-3044(2008)32-1267-02  Netw