(本文由言念小文原创,转载请注明出处)

一  前言
有Android开发经验的同学都清楚,UI的更新必须在主线程中进行,且主线程不能被阻塞,否则系统ANR异常。我们往往做一些数据处理是耗时操作,必须要在子线程中进行,然后再将处理后的数据切换到主线程去更新UI,这便是线程切换。
线程切换的本质是“数据的切换”,即将数据从一个线程传递到另一个线程。

二  案例描述
老风格,先给出场景案例,然后通过线程切换实现该案例。
案例:在线程A中调用api发送一段数据data,data最终通过线程切换由线程B执行数据处理动作。

三  线程切换基本原理
所谓线程切换,本质就是“数据在线程间切换”,即将一个线程A中的数据,传递到另一个线程B执行数据处理操作。基于以上认知,比较自然的实现逻就是:将线程A中的数据进行拷贝,线程B获取到拷贝数据,然后进行处理,如下图所示。

四 案例实现代码

首先创建一个DataHandler类,该类中定义了数据拷贝方法和数据处理线程。在DataHandler中定义了一个用于数据副本存放的成员变量mData;外部模块可通过sendData()将数据拷贝到DataHandler中;在DataHandler构造中初始化数据处理线程(线程B);该线程重写的run()方法中用一个while循环不停查询数据副本mData的值,当检测到mData有数据时,则执行数据处理动作,数据处理完成后,将数副本mData清空。这样便实现了将其他外部线程中的数据切换到线程B中处理。

public class DataHandler {

    // 数据副本
private String mData; public DataHandler() {
initSwithThread();
} /**
* 发送数据,供外部调用
* @param data
*/
public void sendData(String data) {
// 拷贝数据
mData = data;
} private void initSwithThread() {
new Thread(new Runnable() { @Override
public void run() {
while(true) {
if(null != mData && mData.length() > 0) {
System.out.println("process data, run in thread : "
+ Thread.currentThread().getName() + ", data = " + mData);
// 数据发送后,清除数据副本mData
mData = null;
}
// 为了能够清晰看清结果这里让thread休眠1s
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "ThreadB").start();
}
}

测试类ThreadTest中创建线程A,然后在A中调用DataHandler实例的数据拷贝方法sendData()将数据切换到线程B中处理。

public class ThreadTest {

    public static DataHandler mHandler;

    public static void main(String[] args) {

        mHandler = new DataHandler();

        Thread threadA = new Thread(new Runnable() {

            @Override
public void run() {
// 线程A中发送数据
String data = "hello code 9527";
System.out.println("send data, run in thread : "
+ Thread.currentThread().getName() + ", data = " + data);
// 通过DataHandler将数据拷贝到线程B中处理
mHandler.sendData(data); }
}, "threadA");
threadA.start(); } }

运行结果:
send data, run in thread : threadA, data = hello code 9527
process data, run in thread : ThreadB, data = hello code 9527

从结果可以看出数据“hello code 9527”在线程A中被DataHandler拷贝出来,副本存放到DataHandler中,然后通过线程B中进行处理。这样就实现了数据在线程间的切换。实现切换的“灵魂操作”便是“数据拷贝”和“目标线程对拷贝副本的轮询”。实现原理是不是很简单?其实Android的Handler机制也是基于这种原理实现的,有兴趣的同学可以深入分析一下Handler源码。

Java线程切换(一)的更多相关文章

  1. 基于 JVMTI 实现 Java 线程的监控(转)

    随着多核 CPU 的日益普及,越来越多的 Java 应用程序使用多线程并行计算来充分发挥整个系统的性能.多线程的使用也给应用程序开发人员带来了巨大的挑战,不正确地使用多线程可能造成线程死锁或资源竞争, ...

  2. Java线程状态切换以及核心方法

    1.Java线程状态 1.1 线程主要状态 ①初始(NEW):新创建了一个线程对象,但还没有调用start()方法.②运行(RUNNABLE):Java线程中将就绪(ready)和运行中(runnin ...

  3. java中线程切换的开销

    思路: 开三个线程A,B,C 线程A不断的调用LockSupport.park()阻塞自己,一旦发现自己被唤醒,调用Thread.interrupted()清除interrupt标记位,同时增加自增计 ...

  4. Java线程生命周期与状态切换

    前提 最近有点懒散,没什么比较有深度的产出.刚好想重新研读一下JUC线程池的源码实现,在此之前先深入了解一下Java中的线程实现,包括线程的生命周期.状态切换以及线程的上下文切换等等.编写本文的时候, ...

  5. Java线程状态及切换

    Java线程状态及切换 一.什么是Java线程状态 在Java程序中,用于描述Java线程的六种状态: 新建(NEW):当前线程,刚刚新建出来,尚未启动. 运行(RUNNABLE):当前线程,处于竞争 ...

  6. 透彻讲解,Java线程的6种状态及切换

    Java中线程的状态分为6种. 1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法.2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running) ...

  7. Java线程的6种状态及切换

    Java中线程的状态分为6种. 1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法.2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running) ...

  8. 并发编程——Java线程的6种状态及切换

    前言 本次主要分享一下Java线程的六种状态及其转换. 如果对于线程的创建方式不太了解,推荐观看并发编程--认识java里的线程 线程的状态及其转换 操作系统线程的五种状态 新建(NEW) 就绪(RU ...

  9. Java线程的概念

    1.      计算机系统 使用高速缓存来作为内存与处理器之间的缓冲,将运算需要用到的数据复制到缓存中,让计算能快速进行:当运算结束后再从缓存同步回内存之中,这样处理器就无需等待缓慢的内存读写了. 缓 ...

随机推荐

  1. 为elastic的索引做快照并恢复快照到新集群

    1. 为指定的所有做快照 curl -XPUT "192.168.1.1:9200/_snapshot/my_backup/testindex_20170803?wait_for_compl ...

  2. MySQL 相关规约(v1.0)

    0)前言 a. 基本规约 [强制]表存储引擎必须使用InnoDB(针对主库一般是强制要求的) [强制]表字符集默认使用utf8,必要时候使用utf8mb4(个人踩坑:emoji表情存储问题) 说明: ...

  3. 在Debian上用FVWM做自己的桌面

    用FVWM做自己的桌面 Table of Contents 1. 前言 2. 学习步骤 3. 准备 3.1. 软件包 3.2. 字体 3.3. 图片 3.4. 参考资料 4. 环境 5. 布局 6. ...

  4. 面试并发volatile关键字时,我们应该具备哪些谈资?

    提前发现更多精彩内容,请访问 个人博客 提前发现更多精彩内容,请访问 个人博客 提前发现更多精彩内容,请访问 个人博客 写在前面 在 可见性有序性,Happens-before来搞定 文章中,happ ...

  5. 读《深入理解Elasticsearch》点滴-查询二次评分

    理解二次评分 二次评分是指重新计算查询返回文档中指定个数文档的得分,es会截取查询返回的前N个,并使用预定义的二次评分方法来重新计算他们的得分 小结 有时候,我们需要显示查询结果,并且使得页面上靠前文 ...

  6. springboot 整合ehcache缓存

    1.CacheManager Spring Boot默认集成CacheManager,如下包所示: 可以看出springboot自动配置了 JcacheCacheConfiguration. EhCa ...

  7. j2ee开发之Spring2.5框架学习笔记

    Spring 2.5框架学习笔记 1.是一个开源的控制反转IOC和面向切面AOP的容器框架 2.IOC控制反转 public class PersonServiceBean { private Per ...

  8. 【SQL server基础】SQL存储过程和函数的区别

    本质上没区别.只是函数有如:只能返回一个变量的限制.而存储过程可以返回多个.而函数是可以嵌入在sql中使用的,可以在select中调用,而存储过程不行.执行的本质都一样.      函数限制比较多,比 ...

  9. 无法导入要素类到SDE中

    我遇到的原因的表空间不足(并且表空间没有设置为自动增长) 首先通过SELECT FILE_NAME, TABLESPACE_NAME, AUTOEXTENSIBLE FROM DBA_DATA_FIL ...

  10. java基础之泛型对象与json互转

    1. 场景描述 把泛型对象转成字符串放到缓存中,获取后使用有点问题,记录下,有碰到的朋友,参考下. 2. 解决方案 2.1 操作类及说明 /** * @auther: 软件老王 */ public s ...