在日常事务中,我们常常依次做如下操作: 排队取得一个单号; 根据这个单号享有一个操作; 为当前的这个操作买单.
在Android中也一样,为了不阻塞主线程,我们把所有耗时行为都封装为多个线程,有的时候需要先运行线程A,根据得到的结果再运行线程B, 再根据B的结果运行线程C. 时序图如下:
如果我们在ThreadA结束前的代码中插入ThreadB.start, 再ThreadB的结束前的代码中插入ThreadC.start. 那这样的代码很难读,从整体上看也像棉花糖一样无比壮大....
其实在android中有比较优雅的简单的方式处理这个。如下以两个Thread为例子展开演进:
conditionVariableForConnection = new ConditionVariable();
app.method01(param1, param2, new callback01() {
@Override
public void method4Callback01(Object result01) {
conditionVariableForRequestSession.open();
...
}
};
conditionVariableForRequestSession.block(SESSION_WAIT_TIME_MS);
if(getSession()) {
app.method02(param01,param02,callback02(){});
}
...
ExecutorService executorService = Executors.newSingleThreadExecutor();
Callable<String> callback01 = new Callable<String>() {
@Override
public String call() throws Exception {
return HttpHelper.getURLRequestHeadInfo("url01");
}
};
Future<String> future01 = executorService.submit(callback01);
Callable<String> callback02 = new Callable<String>() {
@Override
public String call() throws Exception {
return HttpHelper.getURLRequestHeadInfo("url02");
}
};
Future<String> future02 = executorService.submit(callback02);
if(HttpHelper.isSessionAvaiable(future01.get()) && HttpHelper.isSessionAvaiable(future02.get()) ) {
...
}
总结:
上述两种方式都是用同步的方式进行着异步的处理,代码的直观性和可移植性成倍增加
ConditionVariable方式主要用来协同多个开发员之间的接口或与老系统的交接。随着交互接口的增多需要多次使用ConditionVariable,但是他的可读性比我们棉花糖式的代码有了直接改观;
ExecutorService方式在上下文数据交互(根据前一线程结果来运行新的线程)方面很优雅,整体效率也更高点
- 大小: 7.6 KB
分享到:
相关推荐
阻塞队列提供了四种处理方法: 抛出异常:是指当阻塞队列满时候,再往队列里插入元素,会抛出IllegalStateException(“Queue full”)异常。当队列为空时,从队列里获取元素时会抛出NoSuchElementEx
在项目启动时,开一个单线程来专门处理巡检任务的下发给巡检服务组件。使用BlockingQueue阻塞算法。BlockingQueue作为线程容器,可以为线程同步提供有力的保障。
文章目录一、线程池组成二、线程安全队列的实现三、测试逻辑3.1、测试阻塞逻辑3.2、测试读写加锁逻辑 一、线程池组成 一个完整的线程池由下面几部分组成,线程安全队列、任务对象、线程处理对象、线程池对象。其中...
(2)服务器端能够分别记录已经成功处理的不同运算类型请求的个数。 (2)客户端与服务器端之间基于 UDP 协议进行通信。 (3)应用层协议自行设计。例如请求数据包、响应数据包可以采用如下格式: (4)服
使用队列做缓冲池,通过工作者线程来处理并任务,实现线程空闲时阻塞,有任务令牌时回复服务。
本资源是原始TCP接收目标数据,然后通过多线程处理后存放到阻塞队列,最后MFC的绘图线程从阻塞队列取出数据后显示到表格上。
9)线程阻塞的条件(重要) 14 10) Interrupt()注意事项 16 三. 线程之间协作 17 1)演示简单的消费者和生产者的例子: 17 2)管道的读写流处理方式 19 3)重要的演示死锁的问题—哲学家就餐问题 20 4)终止多线程程序的两种...
若消息队列为空,线程则会阻塞等待。 说了这一堆,那么和Handler 、 Looper 、Message有啥关系?其实Looper负责的就是创建一个MessageQueue,然后进入一个无限循环体不断从该MessageQueue中读取消息,而消息的创建者...
3)推送数据到阻塞队列中 4)如果推送成功就发送Response(200) 5) 如果推送不成功发送Response(500) 保存数据线程 1)从阻塞队列中拉取日志数据 2)保存日志数据到服务器日志文件中 3)如果日志文件...
并发安全的阻塞队列类:需要设计一个线程安全的队列类,支持多线程的插入和移除操作,能够正确处理队列为空或队列已满的情况。 生产者-消费者模型:需要设计一个多线程程序,其中有多个生产者和多个消费者,生产者...
线程池的简介 线程池就是首先创建一些线程,它们的...工作队列本质上是一个阻塞队列。 当工作队列被占满,再来的新请求会交给临时线程来处理。 临时线程在使用完成之后会继续存活一段时间,直到没有请求处理才会被销毁
Timer 是单线程的会有阻塞的风险,并且对异常没有做处理,一个任务出错 Timer 就挂了。而 ScheduledThreadPool 相比于 Timer 首先可以多线程来执行任务,并且线程池对异常做了处理,使得 任务之间不会有影响。 并且 ...
具有阻塞的线程安全队列(比BlockingCollection快5倍); 允许控制客户端输入的一些代码块; 允许限制每秒的最大请求数; -简单的控制反转容器; 弱引用订阅者的事件; -组织为双端队列元素的集合; -具有有限数量...
事件回调支持同步或异步,每工作者可以指定执行超时时间,避免线程阻塞死掉。队列采用线程安全的BlockingCollection,每组工作者用一个队列。委托采用Func来定义的,没有采用传统且不太好理解的Delegate。这让代码...
Windows采用多优先级队列,windows为每个优先级的线程都准备了优先级队列,同一优先级各线程按时间片轮转进行调度,多处理器可以多线程并行。 Windows没有单独的调度模块或程序,调度的代码是在内核中实现的,广泛...
生产者和消费者彼此之间不直接通讯,而是通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不直接找生产者要数据,而是从阻塞队列里取,阻塞队列就相当于一
为了获得尽可能低的延迟,人们无法承受OS内核中的阻塞,因为阻塞线程的唤醒延迟约为1-3微秒,而此队列的往返时间可以低至150纳秒。 超低延迟应用程序仅需此而已。 极简主义带来了回报,请参阅。 可用的容器有: ...
1.1 创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处理效率。 记创建线程消耗时间T1,执行任务消耗时间T2,销毁线程消耗时间T3,如果T1+T3>T2,那说明开启一个线程来执行这个任务太不...
而 SendMessage 等待消息被处理完了之后才返回,如果消息不被处理,发送消息的线程将一直被阻塞。 3、如果在同一个线程内,SendMessage 发送消息时,由 USER32.DLL 模块调用目标窗口的消息处理程序,并将结果返回。...
线程的调度如果只考虑线程优先级的话,那么在线程执行队列中,如果有高优先级的线程插入,该线程就会插入到低优先级线程的前方,这样可能导致低优先级的线程无法执行,最终造成低优先级线程无法获取cpu处理权二导致...