使用回调和线程处理一个耗时响应过程
现在程序中有许多涉及长耗时响应过程的处理,比如访问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() 除此之外没有其他功能
分享到:
相关推荐
Windows 应用程序编程中常见的一个模式就是,在GUI用户界面下,将耗时的文件和网络处理放入 子线程,以避免用户界面不能响应的问题。在.NET出现以前,创建线 程并监视线程结束,还要更新 界面等工作,即复杂又要手写...
Android是一个单线程模型,Android界面(UI)的绘制都只能在主线程中进行,如果在主线程中进行耗时的操作,就会影响UI的绘制和事件的响应。所以在android规定,不可在主线中进行耗时操作,否则将发生程序无响应(ANR...
耗时的操作使用线程,提高应用程序响应 2.并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求。 3.多CPU系统中,使用线程提高CPU利用率 4.改善程序结构。一个既长又复杂的进程可以考虑分为多个线程...
异步:非阻塞式调用,立即返回,调用方无需等待响应方返回实际结果,响应方会通过状态、通知或回调来告知调用方 异步调用场景: 1.耗时任务:主线程中提交耗时任务到线程池,然后通过Feture来异步获取任务执行
所谓异步执行,不同于同步执行(程序的执行顺序与任务的排列顺序是一致的、同步的),每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前...
今天来讲一讲在面试中碰到的Android异常与性能优化相关问题: ... 没有使用子线程的Looper的Handler的handlerMessage,post(Runnable)是执行在主线程的 AsyncTask的回调中除了doInBackground,其它都
网络请求:基于RxJava+Retrofit+Gson+FDroid的封装,支持对网络请求结果的统一处理、请求结果回调到UI线程、自动判断网络连接状态、自动管理生命周期、模拟后台返回数据、自定义请求头、请求响应日志打印、每个阶段...
缺点:只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务...
deferred对象是jQuery对Promises接口的实现。它是非同步操作的通用接口,可以被看作是一个等待完成的任务,开发者...为了避免整个程序失去响应,通常的解决方法是将那些排在后面的操作,写成“回调函数”(callback)的
坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务...
坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务...
坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务...
Android中的IntentService是继承自Service类的,在我们讨论IntentService之前,我们先想一下Service的特点: Service的回调方法(onCreate、onStartCommand、onBind、onDestroy)都是运行在主线程中的。当我们通过start...
F 修复 PC 端模拟器的 touchend 事件回调参数 changedTouches 为空的问题 反馈详情 2020.03.25 更新说明 A 新增 云开发控制台支持开通按量付费 A 新增 云开发支持数据库备份与回档(还原)详情 A 新增 支持小...