- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章深入Android Handler与线程间通信ITC的详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
在《android handler之消息循环的深入解析》中谈到了handler是用于操作线程内部的消息队列,所以handler可以用来线程间通信itc,这种方式更加安全和高效,可以大大减少同步的烦恼,甚至都可以不用syncrhonized。 线程间通讯itc 正常情况下函数调用栈都会生存在同一个线程内,想要把执行逻辑交换到其他线程可以新建一个thread,然后start()。另外一种方法就是用itc,也即用消息队列来实现,线程需要把执行逻辑交到其他线程时就向另外的线程的消息队列发送一个消息,发送消息后函数就此结束返回,调用栈也停止。当消息队列中有了消息时,线程会被唤醒来执行处理消息,从而把执行逻辑从一个线程转到另外一个线程。这就实现了线程间的通信itc,与进行间通讯ipc有十分类似的思想。 通常的做法都是,在主线程创建一个handler,然后在新建线程中使用此handler与主线程通讯。因为主线程的消息队列已经建好,所以直接创建handler即可,新建的线程就可以直接使用。 有些情况,需要在多线程之间进行通信,这就要为每个线程都创建messagequeue和handler,只要线程能访问其他线程的handler就可以与之通信。 要正确的创建handler,因为handler要与线程绑定,所以在初始化handler的时候就要注意: 如果给handler指定looper对象new handler(looper),那么此handler便绑定到looper对象所在的线程中,handler的消息处理回调会在那个线程中执行。 如果创建线程时不指定looper对象,那么此handler绑定到创建此handler的线程内,消息回调处理会在那个线程中执行,所以像下面的例子,如果这样写:
复制代码 代码如下
private class cookserver extends thread { private handler mhandler = new handler() { public void handlemessage(message msg) { .... } },
那么,此mhandler会与创建此cookerserver的线程绑定,handlemessage也会运行于其中。显然,如果是主线程调用new cookserver(),那么mhandler其实是运行在主线程中的。正确的写法应该是:
复制代码 代码如下
private class cookserver extends thread { public void run() { looper.prepare(); // or new handler(looper.mylooper()) private handler mhandler = new handler() { public void handlemessage(message msg) { .... } },
handlerthread 如果要在一个线程中使用消息队列和handler,android api中已经有封装好了的一个类handlerthread,这个类已经做好了looper的初始化工作,你需要做的就是重写其onlooperprepared()方法,在其中创建handler:
复制代码 代码如下
private class deliverserver extends handlerthread { private handler mhandler; public deliverserver(string name) { super(name); } @override public void onlooperprepared() { mhandler = new handler(getlooper()) { public void handlemessage(message msg) { ..... } }; } } 。
实例 此实例模拟了一个网络订餐系统,客户点击“submit order"来产生一个定单,主线程中负责收集定单,然后交由cookserver来制作,cookserver在制作完成后会交由deliverserver来把食物运送到客户,至此一个定单完成,同时cookserver和deliverserver会更新状态.
复制代码 代码如下
/** * how to attach an handler to a thread: * if you specify looper object to handler, i.e. new handler(looper), then the handler is attached to the thread owning * the looper object, in which handlemessage() is executed. * if you do not specify the looper object, then the handler is attached to the thread calling new handler(), in which * handlemessage() is executed. * in this example, for class cookserver or deliverserver, if you write this way: * private class cookserver extends thread { private handler mhandler; private looper mlooper; public cookserver() { mhandler = new handler() { @override public void handlemessage(message msg) { .... } start(); } * then mhandler is attached to thread calling new cookserver(), which is the main thread, so mhandler.handlemessage() will * be executed in main thread. * to attach mhandler to its own thread, you must put it in run(), or after mlooper is created. for our example, providing * mlooper or not won't matter, because new handler() is called in run(), which is in a new thread. */ public class handleritcdemo extends listactivity { private static final int cooking_started = 1; private static final int cooking_done = 2; private static final int delivering_started = 3; private static final int order_done = 4; private listview mlistview; private static final string[] mfoods = new string[] { "cubake", "donut", "eclaire", "gingerbread", "honeycomb", "ice cream sanwitch", "jelly bean", }; private arraylist<string> morderlist; private textview mgeneralstatus; private button msubmitorder; private static random mrandomer = new random(47); private int mordercount; private int mcookingcount; private int mdeliveringcount; private int mdonecount; private handler mmainhandler = new handler() { @override public void handlemessage(message msg) { switch (msg.what) { case cooking_started: mcookingcount++; break; case cooking_done: mcookingcount--; break; case delivering_started: mdeliveringcount++; break; case order_done: mdeliveringcount--; mdonecount++; default: break; } mgeneralstatus.settext(makestatuslabel()); } }; private cookserver mcookserver; private deliverserver mdeliverserver; @override protected void ondestroy() { super.ondestroy(); if (mcookserver != null) { mcookserver.exit(); mcookserver = null; } if (mdeliverserver != null) { mdeliverserver.exit(); mdeliverserver = null; } } @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); mlistview = getlistview(); morderlist = new arraylist<string>(); mgeneralstatus = new textview(getapplication()); mgeneralstatus.settext(makestatuslabel()); msubmitorder = new button(getapplication()); msubmitorder.settext("submit order"); msubmitorder.setonclicklistener(new view.onclicklistener() { public void onclick(view v) { string order = mfoods[mrandomer.nextint(mfoods.length)]; morderlist.add(order); mordercount = morderlist.size(); mgeneralstatus.settext(makestatuslabel()); setadapter(); mcookserver.cook(order); } }); mlistview.addheaderview(mgeneralstatus); mlistview.addfooterview(msubmitorder); setadapter(); mcookserver = new cookserver(); mdeliverserver = new deliverserver("deliver server"); } private string makestatuslabel() { stringbuilder sb = new stringbuilder(); sb.append("total: "); sb.append(mordercount); sb.append(" cooking: "); sb.append(mcookingcount); sb.append(" delivering: "); sb.append(mdeliveringcount); sb.append(" done: "); sb.append(mdonecount); return sb.tostring(); } private void setadapter() { final listadapter adapter = new arrayadapter<string>(getapplication(), android.r.layout.simple_list_item_1, morderlist); setlistadapter(adapter); } private class cookserver extends thread { private handler mhandler; private looper mlooper; public cookserver() { start(); } @override public void run() { looper.prepare(); mlooper = looper.mylooper(); mhandler = new handler(mlooper, new handler.callback() { public boolean handlemessage(message msg) { new cooker((string) msg.obj); return true; } }); looper.loop(); } public void cook(string order) { if (mlooper == null || mhandler == null) { return; } message msg = message.obtain(); msg.obj = order; mhandler.sendmessage(msg); } public void exit() { if (mlooper != null) { mlooper.quit(); mhandler = null; mlooper = null; } } } private class cooker extends thread { private string order; public cooker(string order) { this.order = order; start(); } @override public void run() { mmainhandler.sendemptymessage(cooking_started); systemclock.sleep(mrandomer.nextint(50000)); mdeliverserver.deliver(order); mmainhandler.sendemptymessage(cooking_done); } } private class deliverserver extends handlerthread { private handler mhandler; public deliverserver(string name) { super(name); start(); } @override protected void onlooperprepared() { super.onlooperprepared(); mhandler = new handler(getlooper(), new handler.callback() { public boolean handlemessage(message msg) { new deliver((string) msg.obj); return true; } }); } public void deliver(string order) { if (mhandler == null || getlooper() == null) { return; } message msg = message.obtain(); msg.obj = order; mhandler.sendmessage(msg); } public void exit() { quit(); mhandler = null; } } private class deliver extends thread { private string order; public deliver(string order) { this.order = order; start(); } @override public void run() { mmainhandler.sendemptymessage(delivering_started); systemclock.sleep(mrandomer.nextint(50000)); mmainhandler.sendemptymessage(order_done); } } } 。
最后此篇关于深入Android Handler与线程间通信ITC的详解的文章就讲到这里了,如果你想了解更多关于深入Android Handler与线程间通信ITC的详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
大家好,我是汤师爷~ 什么是订单履约系统? 订单履约是从消费者下单支付到收到商品的全流程管理过程,包括订单接收、订单派单、库存分配、仓储管理和物流配送等环节,核心目标是确保商品准时、准确地送达消费
大家好,我是汤师爷~ 今天聊聊促销系统整体规划。 各类促销活动的系统流程,可以抽象为3大阶段: B端促销活动管理:商家运营人员在后台系统中配置和管理促销活动,包括设定活动基本信息、使用规则
全称“Java Virtual Machine statistics monitoring tool”(statistics 统计;monitoring 监控;tool 工具) 用于监控虚拟机的各种运
主要是讲下Mongodb的索引的查看、创建、删除、类型说明,还有就是Explain执行计划的解释说明。 可以转载,但请注明出处。  
1>单线程或者单进程 相当于短链接,当accept之后,就开始数据的接收和数据的发送,不接受新的连接,即一个server,一个client 不存在并发。 2>循环服务器和并发服务器
详解 linux中的关机和重启命令 一 shutdown命令 shutdown [选项] 时间 选项: ?
首先,将json串转为一个JObject对象: ? 1
matplotlib官网 matplotlib库默认英文字体 添加黑体(‘SimHei')为绘图字体 代码: plt.rcParams['font.sans-serif']=['SimHei'
在并发编程中,synchronized关键字是常出现的角色。之前我们都称呼synchronized关键字为重量锁,但是在jdk1.6中对synchronized进行了优化,引入了偏向锁、轻量锁。本篇
一般我们的项目中会使用1到2个数据库连接配置,同程艺龙的数据库连接配置被收拢到统一的配置中心,由DBA统一配置和维护,业务方通过某个字符串配置拿到的是Connection对象。  
实例如下: ? 1
1. MemoryCahe NetCore中的缓存和System.Runtime.Caching很相似,但是在功能上做了增强,缓存的key支持object类型;提供了泛型支持;可以读缓存和单个缓存
argument是javascript中函数的一个特殊参数,例如下文,利用argument访问函数参数,判断函数是否执行 复制代码 代码如下: <script
一不小心装了一个Redis服务,开了一个全网的默认端口,一开始以为这台服务器没有公网ip,结果发现之后悔之莫及啊 某天发现cpu load高的出奇,发现一个minerd进程 占了大量cpu,googl
今天写这个是为了 提醒自己 编程过程 不仅要有逻辑 思想 还有要规范 代码 这样可读性 1、PHP 编程规范与编码习惯最主要的有以下几点: 1 文件说明 2 funct
摘要:虚拟机安装时一般都采用最小化安装,默认没有lspci工具。一台测试虚拟网卡性能的虚拟机,需要lspci工具来查看网卡的类型。本文描述了在一个虚拟机中安装lspci工具的具体步骤。 由于要测试
1、修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统
目录 算术运算符 基本四则运算符 增量赋值运算符 自增/自减运算符 关系运算符 逻
如下所示: ? 1
MapperScannerConfigurer之sqlSessionFactory注入方式讲解 首先,Mybatis中的有一段配置非常方便,省去我们去写DaoImpl(Dao层实现类)的时间,这个
我是一名优秀的程序员,十分优秀!