Java線程切換(一)

(本文由言念小文原創,轉載請註明出處)api

一  前言
有Android開發經驗的同窗都清楚,UI的更新必須在主線程中進行,且主線程不能被阻塞,不然系統ANR異常。咱們每每作一些數據處理是耗時操做,必需要在子線程中進行,而後再將處理後的數據切換到主線程去更新UI,這即是線程切換。
線程切換的本質是「數據的切換」,即將數據從一個線程傳遞到另外一個線程。ide

 

二  案例描述
老風格,先給出場景案例,而後經過線程切換實現該案例。
案例:在線程A中調用api發送一段數據data,data最終經過線程切換由線程B執行數據處理動做。測試

 

三  線程切換基本原理
所謂線程切換,本質就是「數據在線程間切換」,即將一個線程A中的數據,傳遞到另外一個線程B執行數據處理操做。基於以上認知,比較天然的實現邏就是:將線程A中的數據進行拷貝,線程B獲取到拷貝數據,而後進行處理,以下圖所示。spa

 

 

 

四 案例實現代碼線程


首先建立一個DataHandler類,該類中定義了數據拷貝方法和數據處理線程。在DataHandler中定義了一個用於數據副本存放的成員變量mData;外部模塊可經過sendData()將數據拷貝到DataHandler中;在DataHandler構造中初始化數據處理線程(線程B);該線程重寫的run()方法中用一個while循環不停查詢數據副本mData的值,當檢測到mData有數據時,則執行數據處理動做,數據處理完成後,將數副本mData清空。這樣便實現了將其餘外部線程中的數據切換到線程B中處理。code

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中處理。blog

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源碼。get

相關文章
相關標籤/搜索