APP下载

MSDP多线程技术的实现

2013-04-19金艳夏仕安张佑龙方素贞朱生水

中国高新技术企业·综合版 2013年2期

金艳 夏仕安 张佑龙 方素贞 朱生水

摘要:MSDP是广东省地震局开发的地震交互分析处理软件,在我们的日常工作中发挥了重要作用。文章就MSDP的多线程技术进行了简要分析,以便加深对MSDP的基本原理的了解和掌握。

关键词:MSDP;多线程;JAVA;线程优先级

中图分类号:TP274 文献标识码:A 文章编号:1009-2374(2013)05-0020-03

1 概述

MSDP是地震系统常用的地震交互分析处理软件,MSDP采用了大量的Java技术,Java多线程就是其中之一。

在Java语言产生前,传统的程序设计语言的程序同一时刻只能单任务操作,效率非常低,例如程序往往在接收数据输入时发生阻塞,只有等到程序获得数据后才能继续运行。随着Internet的迅猛发展,这种状况越来越不能让人们忍受:如果网络接收数据阻塞,后台程序就处于等待状态而不继续任何操作,而这种阻塞是经常会碰到的,此时CPU资源被白白地闲置起来。如果在后台程序中能够同时处理多个任务,该多好啊!应Internet技术而生的Java语言解决了这个问题,多线程程序是Java语言的一个很重要的特点。在一个Java程序中,我们可以同时并行运行多个相对独立的线程,例如,我们如果创建一个线程来进行数据输入输出,而创建另一个线程在后台进行其他的数据处理,如果输入输出线程在接收数据时阻塞,而处理数据的线程仍然在运行。多线程程序设计大大提高了程序的执行效率和处理能力。

2 多线程的概念

每个正在系统上运行的程序都是一个进程。每个进程包含一到多个线程。进程也可能是整个程序或者是部分程序的动态执行。线程是一组指令的集合或者是程序的特殊段,它可以在程序里独立执行,也可以把它理解为代码运行的上下文。所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务。通常由操作系统负责多个线程的调度和执行。

线程是程序中一个单一的顺序控制流程。在单个程序中同时运行多个线程完成不同的工作,称为多线程。线程和进程的区别在于,子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈和程序计数器为其执行上下文,多线程主要是为了节约CPU时间。

使用多线程的优点:使用线程可以把占据长时间的程序中的任务放到后台去处理;用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度;程序的运行速度可能加快;在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了,在这种情况下可以释放一些珍贵的资源如内存占用等。

3 多线程的创建与使用

3.1 多线程的创建

我们知道Java是面向对象的程序语言,用Java进行程序设计就是设计和使用类,Java为我们提供了线程类Thread来创建线程,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象。下面是创建启动一个线程的语句:

Thread thread1=new Thread();//声明一个对象实例,即创建一个线程;

Thread1.run();//用Thread类中的run()方法启动线程;

从这个例子中,我们可以通过Thread()构造方法创建一个线程,并启动该线程。事实上,启动线程,也就是启动线程的run()方法,而Thread类中的run()方法没有任何操作语句,所以这个线程没有任何操作。要使线程实现预定功能,必须定义自己的run()方法。Java中通常有两种方式定义run()方法:

3.1.1 通过定义一个Thread类的子类,在该子类中重写run()方法。Thread子类的实例对象就是一个线程,显然,该线程有我们自己设计的线程体run()方法,启动线程就启动了子类中重写的run()方法。

3.1.2 因为有时要作为线程运行的类可能已经是某个类层次的一部分,所以就不能再按这种机制创建线程。虽然在同一个类中可以实现任意数量的接口,但Java编程语言只允许一个类有一个父类。同时,某些程序员避免从Thread类导出,因为它强加了类层次。对于这种情况,就要Runnable接口。通过Runnable接口,在该接口中定义run()方法的接口。所谓接口跟类非常类似,主要用来实现特殊功能,如复杂关系的多重继承功能。在此,我们定义一个实现Runnable()接口的类,在该类中定义自己的run()方法,然后以该类的实例对象为参数调用Thread类的构造方法来创建一个

线程。

在具体应用中,采用哪种方法来构造线程体要视情况而定。通常,当一个线程已继承了另一个类时,就应该用第二种方法来构造,即实现Runnable接口。正如它的名字一样,Runnable的实例是可运行的,但它自己并不能直接运行,它需要被Thread对象来包装才能运行。

使用Runnable接口来实现多线程使得我们能够在一个类中包容所有的代码,有利于封装,它的缺点在于,我们只能使用一套代码,若想创建多个线程并使各个线程执行不同的代码,则仍须额外创建类,如果这样的话,在大多数情况下也许还不如直接用多个类分别继承Thread来得紧凑。

3.2 线程的优先级

对于多线程程序,每个线程的重要程度不尽相同,如多个线程在等待获得CPU时间时,往往我们需要优先级高的线程优先抢占到CPU时间得以执行;又如多个线程交替执行时,优先级决定了级别高的线程得到CPU的次数多一些且时间多长一些。这样,高优先级的线程处理的任务效率就高一些。

Java中线程的优先级从低到高以整数1-10表示,共分为10级,设置优先级是通过调用线程对象的setPriority()方法,如上例中,设置优先级的语句为:

thread1 threadone=new thread1();//用Thread类的子类创建线程;

Thread threadtwo=new Thread(new thread2());//用Runnable接口类的对象创建线程;

threadone.setPriority(6);//设置threadone的优先级6;

threadtwo.setPriority(3);//设置threadtwo的优先级3;

threadone.start();threadtwo.start();//strat()方法启动线程;

这样,线程threadone将会优先于线程threadtwo执行,并将占有更多的CPU时间。该例中,优先级设置放在线程启动前,也可以在启动后进行设置,以满足不同的优先级需求。

3.3 线程的状态

线程也是有状态和生命周期的,每个Java程序都会有一个缺省的主线程,对于应用程序applcation来说main方法就是一个主线程。Java语言使用的是Thread类及其子类的对象来表示线程的。创建一个新的线程的生命周期如下状态:

3.3.1 新建:当一个Thread类或者其子类的对象被声明并创建时,新的线程对象处于新建状态,此时它已经有了相应的内存空间和其他资源。

3.3.2 就绪:处于新建状态的线程被启动后,将进入线程队列排队等待CUP服务,这个时候具备了运行的条件,一旦轮到CPU的时候,就可以脱离创建它的主线程独立开始自己的生命周期。

3.3.3 运行:就绪的线程被调度并获得CUP的处理进入了运行状态,每一个Thread类及其子类的对象都有一个重要的run()方法,当线程对象被调度执行的时候,它将自动调用本对象的run()方法,从第一句代码开始执行。所以说对线程的操作应该写到run()方法中。

3.3.4 阻塞:一个正在执行的线程如果在某种情况下不能执行了,进入阻塞状态,这个时候它不能进入排队状态,只有引起了阻塞的原因消失的时候,线程才可以继续进入排队状态等待CUP

处理。

3.3.5 死亡:处于死亡状态的线程不具有继续执行的能力,线程死亡主要的原因是正常运行的线程完成了全部工作,即执行完了run()方法,另外就是被提前强制地终止了。

为了解决对共享存储区的访问冲突,Java引入了同步机制,现在让我们来考察多个线程对共享资源的访问,显然同步机制已经不够了,因为在任意时刻所要求的资源不一定已经准备好了被访问,反过来,同一时刻准备好了的资源也可能不止一个。为了解决这种情况下的访问控制问题,Java引入了对阻塞机制的支持。

阻塞指的是暂停一个线程的执行以等待某个条件发生(如某资源就绪),学过操作系统的同学对它一定已经很熟悉了。Java提供了大量方法来支持阻塞包括sleep()方法、suspend()方法/yield()方法、wait()方法等。

4 结语

多线程虽然在编程中有着巨大的作用,但是多线程本身也有一些缺点:如果有大量的线程,会影响性能,因为操作系统需要在它们之间切换;更多的线程需要更多的内存空间;线程可能会给程序带来更多“bug”,因此要小心使用;线程的中止需要考虑其对程序运行的影响;通常块模型数据是在多个线程间共享的,需要防止线程死锁情况的

发生。

多线程的核心在于多个代码块并行执行,本质特点在于各代码块之间的代码是乱序执行的,因此,程序是否需要多线程、如何合理地利用多线程,就要视程序的需求而定,只有当它完全符合多线程的特点时,多线程机制对线程通信和线程管理的强大支持才能有用武之地。

参考文献

[1] 孙学军.“虚拟测震台网”技术在广西地区的应用[J].地震地磁观测与研究,2008,29(5):65-70.

[2] 孙学军.GIS技术在地震学研究中的应用[J].地球物理

学进展,2005,20(1):160-164.

[3] 孙学军.全国自动地震速报系统介绍[J].地震地磁观测与研究,2010,31(5):158-161.

[4] 邵维忠.面向对象的系统分析[M].南宁:广西科技出版社,1998.

[5] 吴吉义.软件项目管理理论与案例分析[M].北京:中国电力出版社,2007.

[6] 栾跃.软件开发项目管理[M].上海:上海交通大学出版社,2005.

作者简介:金艳(1983-),女,浙江诸暨人,安徽省地震局助理工程师,研究方向:地震震相分析。

(责任编辑:黄银芳)