首页 > 开发 > Java > 正文

J2ME中多线程网络连接编程的分析

2020-02-05 13:46:21
字体:
来源:转载
供稿:网友
  摘 要 介绍并分析了j2me的通用网络连接框架(gcf),并以此为基础,指出了在j2me网络连接编程中存在的问题,并提出了通过构建多线程的两种解决方法。

  关键词 j2me gcf多线程 网络连接

  引言
 
  j2me(java 2 micro edition)是java 2的一个组成部分,它与j2se、j2ee并称。j2me是一种高度优化的java运行环境,主要针对消费类电子设备的,例如蜂窝电话、可视电话、数字机顶盒和汽车导航系统等等。即j2me是为消费电子产品和手持设备量身定制的java专用版本。
j2me的出现使开发跨平台的消费类电子产品的应用软件成为可能。java语言的与平台无关的特性移植到小型电子设备上,允许移动无线设备之间共享应用程序。它提供了基于http的高级internet协议,使移动电话能以client/server方式直接访问internet的全部信息,从而使得不同的client访问不同的资源。

  在将来的无线通信时代中,大量的网络应用程序将被开发出来去满足无线移动通讯的要求,而要充分的发挥无线移动通讯设备的通信能力,j2me网络编程就变得尤为重要。那么为了高效地进行网络编程,就要利用java语言的多线程编程机制。

  1、j2me的网络连接框架(gcf)

  通用连接框架(generic connection framework,gcf)为资源有限的设备提供了一个可扩展的、通用的i/o 框架。gcf 是一组在 javax.microedition.io 包中定义的接口。图 1 显示了 gcf 的类层次结构。


图1 gcf 的类层次结构

  在 gcf 中共定义了七个接口 ,其中 connection 是最基本的连接类型。且同时提供了对数据包和流连接的支持。沿着层次结构向下派生出提供更多功能的接口。例如, streamconnection 接口支持输入流和输出流, contentconnection接口又扩展了 streamconnection 接口以支持对流的内容类型、数据长度和编码格式的确定,httpconnection接口又扩展了contentconnection接口以支持对于标准的http请求。如在框架层规定的适用于手机或双向寻呼机的移动信息设备框架midp(mobile information device profile)在其midp 1.0 规范只要求设备支持 http 连接协议,而更新的 midp 2.0 规范要求同时支持 http 和 https,后者提供了对更安全的网络连接的支持。

  2、网络编程中的多线程

  由于目标设备具有内存小,计算能力弱和电池供电等特点,所以如何使应用程序高效的运行就成为开发中的一个大问题.尤其针对手机等移动信息设备时,无线通讯的特点又对我们的程序提出了更高的要求.从代码优化的角度,在网络编程中引入多线程就显得十分重要。

  当程序运行的时候,application management software(应用管理软件)首先初始化一个midlet,然后调用它的startapp()方法使得midlet进入active状态,这条程序分支就是主线程,它执行其他的方法后都会返回到这个分支上来继续执行。然而网络连接是个可能堵塞的操作,意味着它可能长时间都不返回。

  在sun公司的无线开发包wtk中模拟一段网络连接程序运行时,wtk会提示网络连接工作可能会堵塞用户输入,需要创建另外一个线程去进行联网操作。针对以上情况,引入多线程的处理机制。

  2.1 利用thread类与runnable接口

  编写j2me网络连接应用程序的时候往往借助command显示部件,调用其事件处理函数完成网络的连接工作,代码框架如下:

public void commandaction(command c, displayable s) {
 if(c==sendcommand){
  requestconnect();//连接方法
 }
 else if(
  c==backcommand){
   display.setcurrent(mainform); }
 else{
  destroyapp(false);
  notifydestroyed(); }
}
// 获取一个http的连接
private void requestconnect() {
 string url= url.urlstring
 httpconnection hpc = null;
 try{
  hpc = (httpconnection)connector.open(url);
  int status = hpc.getresponsecode();
  if(status != httpconnection.http_ok)
   content = "联机失败!";
  else
   content = "已联机!";
 }
 catch(ioexception e){system.out.println(content);}
 try{
  if(hpc != null) hpc.close();
 }
 catch(ioexception e2){}}

  上面的程序工作原理可用图2的工作原理图a来表示。


图2 工作原理图a


  分析图2可以得出,如果这样的网络连接程序在手机上运行,那么将可能长时间得不到响应。因为连接工作只有一个主线程,所有的应用都是在这个主线程当中进行的,如果此主线程不返回,那么就不能进行后面的行为,用户也不能进行任何操作。

  下面改进一下程序,创建一个实现runnable接口的connectpipe类来创建多线程。代码如下:

//实现runnable接口
class connectpipe implement runnable{
 ……
 public void run(){
  requestconnect();}
}

  修改commandaction函数:

public void commandaction(command c, displayable s) {
 if(c==sendcommand){
  //创建新线程
  new thread(new connectpipe()).start();
 }
 else if(c==backcommand){
  ……
 }
}

  修改之后程序能够较为顺利的运行,当处理网络连接的时候,启动一个线程后主线程会立刻返回,两个线程并行,不会引发在此地堵塞。其工作原理可用图3的工作原理图b来表示。


图3 工作原理图b

  详细分析图3,又发现尽管程序可以正常工作,但是每次用户按下按钮的时候都会有新的线程产生,这样显然不够高效,同时,异步的行为又有可能使两个线程间产生死锁。幸好java中提供了wait()和notify()/notifyall()来进行线程间的通讯,协调同步问题。那么对应本程序中的线程同步问题,设计思想如下:启动线程后,让其进入等待的状态,当用户激活command事件的时候唤醒线程,才让其继续运行。代码类似如下:

public synchronized void run() {
 while (dealing) {
  try { wait(); }//线程等待
  catch (interruptedexception ie) {}
  if (dealing) requestconnect();
 }
}
public synchronized void deal() {
 notify();//唤醒线程
}

  其中dealing变量用于定义一个锁,当其为true时,当前线程等待,直到用户激活command事件之后,调用deal()方法中的notify()唤醒当前线程继续运行。这样程序就显得相当的高效,也在很大程度上避免了线程间的死锁问题。其工作原理可用图4的工作原理图c来表示。


图4 工作原理图c

  2.2 利用系统类timer和timertask

  系统类timer类是一个计时器,和timertask类结合可以来实现在midlet中定时执行特定任务。需要说明的是每一个timer对象实际上都是一个后台运行的独立的线程。这是因为调度一次的任务都是由timertask类的实现对象负责,timertask类是一个抽象类,它的主要特点是实现了runnable接口,因此扩展了必须实现的public void run()方法。

  所以,在j2me的网络编程中,我们可以利用timer类和timertask类来建立线程,完成网络连接等工作。设计思想如下:创建一个timer类计时器,一个完成网络连接功能的timertask类,在系统空闲时,反复调度任务要求连接,直到连接成功,再调用timertask类的cancel()可以停止一个具体的调度任务。核心代码类似如下:

class connecttimer implement timertask{
 connecttimer (){
  m_timer = new timer();//定义timer
  m_timer.schedule(this,500,5000); //调度任务
 }
 ……
 public synchronized void run(){
  requestconnect();//连接方法
  cancel();//取消任务
 }
}

public void commandaction(command c, displayable s) {
 if(c==sendcommand){
  new connecttimer;}
 else if(c==backcommand){
  ……
 }
}

  3、结束语

  综上所述,在j2me的应用开发中网络程序的设计具有重要的地位,而编程的关键又在于编写高效友好的j2me网络连接程序。通过java语言内置的多线程处理机制,利用线程进行同步并行处理,解决了网络连接时的阻塞问题,达到了程序高效运行的目的。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表