`
achievo_bruce
  • 浏览: 115983 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用回调和线程处理一个耗时响应过程

    博客分类:
  • java
阅读更多
使用回调和线程处理一个耗时响应过程

现在程序中有许多涉及长耗时响应过程的处理,比如访问WebService,远程调用,复杂处理等,如果我们使用直接顺序执行的方式进行处理有可能导致界面停顿,响应停止,无谓等待等缺陷,这是不应该的。

一个耗时响应过程应该采用回调和线程来处理,具体就是把原来的顺序执行修改为异步方式,并让被调用者调用调用者以获得执行结果。在附件的例子中,Viewer就是调用者,它代表界面,而LongTimeResponse是被调用者,它内部用线程启动一个耗时过程,执行完毕再通知调用者。

Viewer类代码如下:
public class Viewer{
private int count;

public Viewer(int count){
this.count=count;
}

public void printNewCount(int newCount){
System.out.println("New Count="+newCount);
}

public int getCount() {
return count;
}

public void setCount(int count) {
this.count = count;
}
}
LongTimeResponse类代码如下,可以看出,它之所以能回调调用者,是因为其内部有调用者的引用viewer,在其构造函数中viewer被赋上了值:
public class LongTimeResponse implements Runnable{
private Viewer viewer;
private int count;

public LongTimeResponse(Viewer viewer){
this.viewer=viewer;
this.count=viewer.getCount();

caculateNewCount();
}

private void caculateNewCount(){
Thread thread=new Thread(this);
thread.start();
}

public void run(){
try{
Thread.sleep(10000);
}
catch(Exception ex){
ex.printStackTrace();
}

viewer.printNewCount(count*count*count);
}
}
调用过程如下:
public class Inlet {
public static void main(String[] arg) {
Viewer viewer=new Viewer(10);
LongTimeResponse longTimeResponse=new LongTimeResponse(viewer);

viewer.printNewCount(123);
}
}

执行起来可以看出,程序先输出了
New Count=123
过了十秒,才输出:
New Count=1000

这说明,程序是异步执行的,耗时过程没有影响到主干程序的运行,而耗时过程完成后,才把返回结果通知了调用者,主干程序没有受到耗时过程的影响,因此也就不会导致界面停顿,响应停止,无谓等待等缺陷。

以上就是使用回调和线程处理一个耗时响应的整个过程。

来自java编程思想:
闭包是一个可调用的对象,它记录了一些信息,这些信息来自于创建他的作用域,用过这个定义 可以看出内部类是面向对象的闭包 因为他不仅包含外围类对象的信息 还自动拥有一个指向此外围类对象的引用 在此作用域内 内部类有权操作所有的成员 包括private成员;
interface Incrementable
{
void increment();
}

class Callee1 implements Incrementable
{
private int i=0;
public void increment()
{
  i++;
  System.out.println(i);
}
}
class MyIncrement
{
void increment()
{
  System.out.println("other increment");
}
static void f(MyIncrement mi)
{
  mi.increment();
}
}
class Callee2 extends MyIncrement
{
private int i=0;
private void incr()
{
  i++;
  System.out.println(i);
}
private class Closure implements Incrementable
{
  public void increment()
  {
   incr();
  }
}
Incrementable getCallbackReference()
{
  return new Closure();
}
}
class Caller
{
  private Incrementable callbackRefference;
  Caller(Incrementable cbh)
  {
   callbackRefference = cbh;
  }
  void go()
  {
   callbackRefference.increment();
  }
}
public class Callbacks
{
public  static void main(String [] args)
{
  Callee1 c1=new Callee1();
  Callee2 c2=new Callee2();
  MyIncrement.f(c2);
  Caller caller1 =new  Caller(c1);
  Caller caller2=new Caller(c2.getCallbackReference());
  caller1.go();
  caller1.go();
  caller2.go();
  caller2.go();
}
}
输出
other increment
1
2
1
2
Callee2继承字MyIncrement 后者已经有一个不同的increment()方法 并且与Incrementable接口期望的increment()方法完全不相关 所以如果Callee2继承了MyIncrement 就不能为了Incrementable的用途而覆盖increment()方法 于是这能使用内部类独立的实现Incrementable
内部类Closure实现了Incrementable 一提供一个放回Caller2的钩子 而且是一个安全的钩子 无论谁获得此Incrementbale的引用 都只能调用increment() 除此之外没有其他功能
分享到:
评论

相关推荐

    C#异步编程概述

    Windows 应用程序编程中常见的一个模式就是,在GUI用户界面下,将耗时的文件和网络处理放入 子线程,以避免用户界面不能响应的问题。在.NET出现以前,创建线 程并监视线程结束,还要更新 界面等工作,即复杂又要手写...

    android AsynTask处理返回数据和AsynTask使用get,post请求

    Android是一个单线程模型,Android界面(UI)的绘制都只能在主线程中进行,如果在主线程中进行耗时的操作,就会影响UI的绘制和事件的响应。所以在android规定,不可在主线中进行耗时操作,否则将发生程序无响应(ANR...

    C/C++笔试题(附答案,华为面试题系列)

    耗时的操作使用线程,提高应用程序响应 2.并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求。 3.多CPU系统中,使用线程提高CPU利用率 4.改善程序结构。一个既长又复杂的进程可以考虑分为多个线程...

    线程—–同步异步,阻塞非阻塞

    异步:非阻塞式调用,立即返回,调用方无需等待响应方返回实际结果,响应方会通过状态、通知或回调来告知调用方 异步调用场景: 1.耗时任务:主线程中提交耗时任务到线程池,然后通过Feture来异步获取任务执行

    理解javascript异步编程

    所谓异步执行,不同于同步执行(程序的执行顺序与任务的排列顺序是一致的、同步的),每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前...

    BAT 大厂Android研发岗必刷真题:Android异常与性能优化相关面试问题

    今天来讲一讲在面试中碰到的Android异常与性能优化相关问题: ... 没有使用子线程的Looper的Handler的handlerMessage,post(Runnable)是执行在主线程的 AsyncTask的回调中除了doInBackground,其它都

    fdroid:优雅的Android MVP开发框架 - 基于RxJava2

    网络请求:基于RxJava+Retrofit+Gson+FDroid的封装,支持对网络请求结果的统一处理、请求结果回调到UI线程、自动判断网络连接状态、自动管理生命周期、模拟后台返回数据、自定义请求头、请求响应日志打印、每个阶段...

    浅谈js的异步执行

    缺点:只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务...

    jQuery之Deferred对象详解

    deferred对象是jQuery对Promises接口的实现。它是非同步操作的通用接口,可以被看作是一个等待完成的任务,开发者...为了避免整个程序失去响应,通常的解决方法是将那些排在后面的操作,写成“回调函数”(callback)的

    JavaScript中实现异步编程模式的4种方法

    坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务...

    javascript异步编程的4种方法

    坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务...

    Javascript异步编程的4种方法让你写出更出色的程序

    坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务...

    详解Android中IntentService的使用方法

    Android中的IntentService是继承自Service类的,在我们讨论IntentService之前,我们先想一下Service的特点: Service的回调方法(onCreate、onStartCommand、onBind、onDestroy)都是运行在主线程中的。当我们通过start...

    【最新版】wechat_devtools_1.02.2004020.dmg【亲测可用】最好的微信开发者工具

    F 修复 PC 端模拟器的 touchend 事件回调参数 changedTouches 为空的问题 反馈详情 2020.03.25 更新说明 A 新增 云开发控制台支持开通按量付费 A 新增 云开发支持数据库备份与回档(还原)详情 A 新增 支持小...

Global site tag (gtag.js) - Google Analytics