Java线程切换(一)
(本文由言念小文原创,转载请注明出处)
一 前言
有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线程切换(一)的更多相关文章
- 基于 JVMTI 实现 Java 线程的监控(转)
随着多核 CPU 的日益普及,越来越多的 Java 应用程序使用多线程并行计算来充分发挥整个系统的性能.多线程的使用也给应用程序开发人员带来了巨大的挑战,不正确地使用多线程可能造成线程死锁或资源竞争, ...
- Java线程状态切换以及核心方法
1.Java线程状态 1.1 线程主要状态 ①初始(NEW):新创建了一个线程对象,但还没有调用start()方法.②运行(RUNNABLE):Java线程中将就绪(ready)和运行中(runnin ...
- java中线程切换的开销
思路: 开三个线程A,B,C 线程A不断的调用LockSupport.park()阻塞自己,一旦发现自己被唤醒,调用Thread.interrupted()清除interrupt标记位,同时增加自增计 ...
- Java线程生命周期与状态切换
前提 最近有点懒散,没什么比较有深度的产出.刚好想重新研读一下JUC线程池的源码实现,在此之前先深入了解一下Java中的线程实现,包括线程的生命周期.状态切换以及线程的上下文切换等等.编写本文的时候, ...
- Java线程状态及切换
Java线程状态及切换 一.什么是Java线程状态 在Java程序中,用于描述Java线程的六种状态: 新建(NEW):当前线程,刚刚新建出来,尚未启动. 运行(RUNNABLE):当前线程,处于竞争 ...
- 透彻讲解,Java线程的6种状态及切换
Java中线程的状态分为6种. 1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法.2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running) ...
- Java线程的6种状态及切换
Java中线程的状态分为6种. 1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法.2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running) ...
- 并发编程——Java线程的6种状态及切换
前言 本次主要分享一下Java线程的六种状态及其转换. 如果对于线程的创建方式不太了解,推荐观看并发编程--认识java里的线程 线程的状态及其转换 操作系统线程的五种状态 新建(NEW) 就绪(RU ...
- Java线程的概念
1. 计算机系统 使用高速缓存来作为内存与处理器之间的缓冲,将运算需要用到的数据复制到缓存中,让计算能快速进行:当运算结束后再从缓存同步回内存之中,这样处理器就无需等待缓慢的内存读写了. 缓 ...
随机推荐
- SpringBoot起飞系列-Web开发(四)
一.前言 从今天你开始我们就开始进行我们的web开发,之前的一篇用SpringBoot起飞系列-使用idea搭建环境(二)已经说明了我们如何进行开发,当然这是搭建起步,接下来我们就开始进行详细的开发, ...
- 一个有意思的js块作用域问题
1.问题 首先把问题放出来,昨天看了一个掘友发的一个问题,然后跟我同事一起研究了一下,没找出来是为什么,然后我回来一直在想为什么,然后各种找资料研究,从各个方面找为什么,比如js上下文,作用域,js垃 ...
- Spring Environment的加载
这节介绍environment,默认环境变量的加载以及初始化. 之前在介绍spring启动过程讲到,第一步进行环境准备时就会初始化一个StandardEnvironment.下图为Environm ...
- invalid comparison: java.util.ArrayList and java.lang.String解决
报错: Caused by: org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause ...
- .Net Core 商城微服务项目系列(八):购物车
最近加班有点多,一周五天,四天加班到11点+,心很累.原因是我当前在的这个组比较特殊,相当于业务的架构组,要为其它的开发组提供服务和监控.所以最近更新的也少,不过这个元旦三天假应该会更新三篇. 这篇是 ...
- 3. Git与TortoiseGit基本操作
1. GitHub操作 本节先简单介绍 git 的使用与操作, 然后再介绍 TortoiseGit 的使用与操作. 先看看SVN的操作吧, 最常见的是 检出(Check out ...), 更新 (U ...
- Dedecms手机站三种不同建设方法和优劣分析
dedecms简单易用功能强大,是国内使用最多的cms建站系统,百度站长平台专门推出了“织梦移动化指南”,由此可见dedecms的影响力.织梦也是站长使用和学习最早的cms建站系统,解放了我的双手,让 ...
- JZOJ10004 列车调度
[JZOJ100041]列车调度 Description Input Output Sample Input Sample1: 3 1 2 3 Sample2: 9 1 3 2 4 8 6 9 5 7 ...
- 第10项:重写equals时请遵守通用约定
重写equals方法看起来似乎很简单,但是有许多重写方式会导致错误,而且后果非常严重.最容易避免这类问题的办法就是不覆盖equals方法,在这种情况下,类的每个实例都只能与它自身相等.如果满足了以 ...
- Vue-CLI项目路由案例汇总
0901自我总结 Vue-CLI项目路由案例汇总 router.js import Vue from 'vue' import Router from 'vue-router' import Cour ...