岁月联盟 · 中国技术网 本站主页 | 安全认证 | 用户服务 | 技术论坛
新闻快报 | 新手学堂 | 黑客特区 | 程序语言 | 数 据 库 | 防 火 墙 | 路由交换 | 系统集成 | 服 务 器 | 存储备份 | 考试认证
Windows | Linux | Java | 协议分析 | 问题解答 | 进程大全 | 网页设计 | 多 媒 体 | 图库资料 | 软件下载 | 站内下载
  您现在的位置: 岁月联盟 >> Java >> 高级技术 >> 多线程 >> Java正文
在Java程序中采用线程获取优异性能
作者:未知 文章来源:本站整理 点击数: 更新时间:2007-7-22 18:10:29

  什么是线程?
  线程的概念并不难于掌握:它是程序代码的一个独立的执行通道。当多个线程执行时,经由相同代码的一个线程的通道通常与其它的不同。例如,假设一个线程执行一段相当于一个if-else语句的if部分的字节代码时,而另一个线程正执行相当于else部分的字节代码。JVM怎样保持对于每一个线程执行的跟踪呢?JVM给每一个线程它自己的方法调用堆栈。另外跟踪当前指令字节代码,方法堆栈跟踪本地变量,JVM传递给一个方法的参数,以及方法的返回值。 
  当多个线程在同一个程序中执行字节代码序列时,这种行为叫作多线程。多线程在多方面有利于程序: 
  ·当执行其它任务时多线程GUI(图形用户界面)程序仍能保持对用户的响应,比如重编页码或打印一个文档。 
  ·带线程的程序一般比它们没有带线程的副本程序完成得快。这尤其表现在线程运行在一个多处理器机器上,在这里每一个线程都有它自己的处理器。
  Java通过java.lang.Thread类完成多线程。每一个线程对象描述一个单独的执行线程。那些运行发生在线程的run()方法中。因为缺省的run()方法什么都不做,你必须创建Thread子类并重载run()以完成有用的工作。练习列表1中领略一个在Thread中的线程及多线程: 
  列表1. ThreadDemo.java 
  // ThreadDemo.java
  class ThreadDemo
  {
  public static void main (String [] args)
  {
  MyThread mt = new MyThread ();
  mt.start ();
  for (int i = 0; i < 50; i++)
  System.out.println ("i = " + i + ", i * i = " + i * i);
  }
  }
  class MyThread extends Thread
  {
  public void run ()
  {
  for (int count = 1, row = 1; row < 20; row++, count++)
  {
  for (int i = 0; i < count; i++)
  System.out.print ('*');
  System.out.print ('\n');
  }
  }
  }
  列表1显示了一个由类ThreadDemo和MyThread组成的应用程序的源代码。类ThreadDemo通过创建一个MyThread对象驱动应用程序,开始一个与其对象相关的线程并执行一段打印一个正方形表的代码。相反, MyThread重载Thread的run()方法打印(通过标准输入流)一个由星形符号组成的直角三角形。 
  当你键入java ThreadDemo运行应用程序时, JVM创建一个运行main()方法的开始线程。通过执行mt.start (),开始线程告诉JVM创建一个执行包含MyThread对象的run()方法的字节代码指令的第二个线程。当start()方法返回时,开始线程循环执行打印一个正方形表,此时另一个新线程执行run()方法打印直角三角形。 
  输出会象什么样呢?运行ThreadDemo就可以看到。你将注意到每一个线程的输出与其它线程的输出相互交替。这样的结果是因为两个线程将它们的输出都发送到了同样的标准输出流。 
  注意
  多数(不是所有)JVM设备使用下层平台的线程性能。因为那些性能是平台特有的,你的多线程程序的输出顺序可能与一些人的其他输出的顺序不一样。这种不同是由于时序的安排,我将在这一系列的稍后探讨这一话题。
  线程类
  要精通写多线程代码,你必须首先理解创建Thread类的多种方法。这部份将探讨这些方法。明确地说,你将学到开始线程的方法,命名线程,使线程休眠,决定一个线程是否激活,将一个线程与另一个线程相联,和在当前线程的线程组及子组中列举所有激活的线程。我也会讨论线程调试辅助程序及用户线程与监督线程的对比。 
  我将在以后的文章中介绍线程方法的余下部份,Sun不赞成的方法除外。 
  警告
  Sun有一些不赞成的线程方法种类,比如suspend()和resume(),因为它们能锁住你的程序或破坏对象。所以,你不必在你的代码中调用它们。考虑到针对这些方法工作区的SDK文件,在这篇文章中我没有包含这些方法。 
  构造线程
  Thread有八个构造器。最简单的是:
  ·Thread(),用缺省名称创建一个Thread对象 
  ·Thread(String name),用指定的name参数的名称创建一个Thread对象
  下一个最简单的构造器是Thread(Runnable target)和Thread(Runnable target, String name)。 除Runnable参数之外,这些构造器与前述的构造器一样。不同的是:Runnable参数识别提供run()方法的线程之外的对象。(你将在这篇文章稍后学到Runnable。)最后几个构造器是Thread(String name),Thread(Runnable target),和Thread(Runnable target, String name)。然而,最后的构造器包含了一个为了组织意图的ThreadGroup参数。 
  最后四个构造器之一,Thread(ThreadGroup group, Runnable target, String name, long stackSize),令人感兴趣的是它能够让你指定想要的线程方法调用堆栈的大小。能够指定大小将证明在使用递归方法(一种为何一个方法不断重复调用自身的技术)优美地解决一些问题的程序中是十分有帮助的。通过明确地设置堆栈大小,你有时能够预防StackOverflowErrors。然而,太大将导致OutOfMemoryErrors。同样,Sun将方法调用堆栈的大小看作平台依赖。依赖平台,方法调用堆栈的大小可能改变。因此,在写调用Thread(ThreadGroup group, Runnable target, String name, long stackSize)代码前仔细考虑你的程序分枝。 
  开始你的运载工具
  线程类似于运载工具:它们将程序从开始移动到结束。Thread 和Thread子类对象不是线程。它们描述一个线程的属性,比如名称和包含线程执行的代码(经由一个run()方法)。当一个新线程执行run()时,另一个线程正调用Thread或其子类对象的start()方法。例如,要开始第二个线程,应用程序的开始线程—它执行main()—调用start()。作为响应,JVM和平台一起工作的线程操作代码确保线程正确地初始化并调用Thread或其子类对象的run()方法。 
  一旦start()完成,多重线程便运行。因为我们趋向于在一种线性的方式中思维,我们常发现当两个或更多线程正运行时理解并发(同时)行为是困难的。因此,你应该看看显示与时间对比一个线程正在哪里执行(它的位置)的图表。下图就是这样一个图表。
  

  与时间对比一个开始线程和一个新建线程执行位置的行为
  
  图表显示了几个重要的时间段: 
  ·开始线程的初始化 
  ·线程开始执行main()瞬间 
  ·线程开始执行start()的瞬间 
  ·start()创建一个新线程并返回main()的瞬间 
  ·新线程的初始化 
  ·新线程开始执行run()的瞬间 
  ·每个线程结束

[1] [2] 下一页


  • 上一个Java:
  • 下一个Java:
  •  
    热门文章
    推荐文章
    关于我们 | 发展历程 | 网站地图 | 广告服务 | 招贤纳士 | 战略合作 | 友情链接 | 著作声明 | 联系我们
    Copyright © 2002-2007 SYUE All rights reserved.
    E_mail:Admin@Syue.Com 皖ICP备05004589号
    未经授权禁止转载、摘编、复制或建立镜像.如有违反,追究法律责任.
    传世私服 传奇世界私服 天龙八部私服 bet365 传世私服 天龙八部私服 热血江湖私服 英雄合击传奇私服 热血江湖私服 bet365 bet365