• Java线程切换(一)


    摘自:https://www.cnblogs.com/woyuwozhouxuanjiu-ningzuowo/p/11774265.html

    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
  • 相关阅读:
    剑指Offer——翻转单词顺序列
    剑指Offer——左旋转字符串
    剑指Offer——和为S的两个数字
    剑指Offer——和为S的连续正数序列
    剑指Offer——数组中只出现一次的数字
    log4cxx入门第一篇--一个小例子
    gsoap写一个c++ webservice
    Protocol Buffer技术详解(数据编码)
    Protocol Buffer技术详解(Java实例)
    Protocol Buffer技术详解(C++实例)
  • 原文地址:https://www.cnblogs.com/xichji/p/11793384.html
Copyright © 2020-2023  润新知