多线程同步(二)

相对于Audio Player MIDlet应用程序,Bouncing Ball MIDlet应用程序相对复杂一点,它的主画面是运动的小球,而且有背景音乐,每个小球放在单独的线程里,背景音乐也是单开一个线程,所以说是一个相对复杂的多线程程序,很值得我们去学习。还是先来看程序,从程序中我们才能知晓作者的用心良苦,

BBall.java 


public class BBall extends MIDlet implements CommandListener, Runnable {

先看它的事件处理

public void commandAction(Command c, Displayable s) {

 if (c == exitCommand) {
     synchronized(gameLock) {
  if (game != null) {
      game.destroy();
      game = null;
  }
     }
     destroyApp(false);
     notifyDestroyed();
 } else if ((s == theList && c == List.SELECT_COMMAND) || c == playCommand) {
     idx = theList.getSelectedIndex();
     new Thread(this).start();
 }
    }

注意最后一行代码是:new Thread(this).start();

BBall类实现了Runnable,下面是它的实现

public void run() {
    System.out.println(Thread.currentThread().getName());
 synchronized(gameLock) {
     if (game == null) {
  game = new BallCanvas(this);
     }
     display.setCurrent(game);
     game.init(8, idx);
     if (game.needAlert()) {
  Alert alert = new Alert("Warning", "Cannot create player", null, null);
  alert.setTimeout(1000);
  display.setCurrent(alert, game);
     }
     game.start();
 }
    }

分析以上代码,不难得出以下几个结论:
  1. 主程序GUI线程(我就叫它GUI线程),负责整个MIDlet程序的初始化显示;
      而比较费CPU时间的game的创建和实例化,单独放在一个线程(我就叫它game线程)里
      这一点是非常有必要的。
  2. 这个类用了一个监视器对象gameLock来实现GUI线程和game线程之间的同步,这个同步的
    必要性,开始我还怀疑过,后来加了以行代码后,才明白它存在的必要性

public void run() {
    System.out.println(Thread.currentThread().getName());
 synchronized(gameLock) {
     if (game == null) {
  game = new BallCanvas(this);
     }
     try{Thread.sleep(10000);}catch(InterruptedException ex){}
     display.setCurrent(game);
     game.init(8, idx);
     if (game.needAlert()) {
  Alert alert = new Alert("Warning", "Cannot create player", null, null);
  alert.setTimeout(1000);
  display.setCurrent(alert, game);
     }
     game.start();
 }
    }

然后生成,运行,单击no background,接着(当然是在十秒种以内了,)要是单击exit的话,你会发现程序并没有退出,原因很简单,game线程已经获得了gameLock的锁,GUI线程只能等待了。

考虑一下,如果此处不同步的话,因为我们不能预测cpu何时,以什么顺序来执行线程,一种情况,game线程在完成game的创建,即game= new BallCanvas(this);,cpu切换到GUI线程(可能这个人想突然退出,不想看效果了) ,执行下面语句
  if (game != null) {
      game.destroy();
      game = null;
  }
  接着cpu又切换到了game线程,灾难发生了,game.init(8,idx);

所以说,在手机这种资源相对有限的设备上写程序,安全设计和性能设计非常重要!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值