Android線程管理之Thread使用總結

前言html

     最近在一直準備總結一下Android上的線程管理,今天先來總結一下Thread使用。java

     線程管理相關文章地址:多線程

實現Thread兩種方式

   1.)繼承Thread類
 /**
     * 繼承Thread方式
     */
    private class SyncThread extends Thread {

        SyncThread(String name) {
            super(name);
        }

        @Override
        public void run() {
           //執行耗時操做
        }
    }

 示例:異步

 SyncThread syncThread1 = new SyncThread("線程一");
 SyncThread syncThread2 = new SyncThread("線程二");
 SyncThread syncThread3 = new SyncThread("線程三");

 syncThread1.start();
 syncThread2.start();
 syncThread3.start();
 2.)實現Runnable接口
   /**
     * 實現Runnable方式
     */
    private class SyncRunnable implements Runnable {
        @Override
        public void run() {
            //執行耗時操做
        }
    }

示例:ide

SyncRunnable syncRunnable = new SyncRunnable();
Thread syncThread1 = new Thread(syncRunnable, "線程一");
Thread syncThread2 = new Thread(syncRunnable, "線程二");
Thread syncThread3 = new Thread(syncRunnable, "線程三");

syncThread1.start();
syncThread2.start();
syncThread3.start();

Thread主要函數

run()//包含線程運行時所執行的代碼 函數

start()//用於啓動線程this

sleep()/sleep(long millis)//線程休眠,交出CPU,讓CPU去執行其餘的任務,而後線程進入阻塞狀態,sleep方法不會釋放鎖spa

yield()//使當前線程交出CPU,讓CPU去執行其餘的任務,但不會是線程進入阻塞狀態,而是重置爲就緒狀態,yield方法不會釋放鎖線程

join()/join(long millis)/join(long millis,int nanoseconds)//等待線程終止,直白的說 就是發起該子線程的線程 只有等待該子線程運行結束才能繼續往下運行code

wait()//交出cpu,讓CPU去執行其餘的任務,讓線程進入阻塞狀態,同時也會釋放鎖

interrupt()//中斷線程,自stop函數過期以後,咱們經過interrupt方法和isInterrupted()方法來中止正在運行的線程,注意只能中斷已經處於阻塞的線程

getId()//獲取當前線程的ID

getName()/setName()//獲取和設置線程的名字

getPriority()/setPriority()//獲取和這是線程的優先級 通常property用1-10的整數表示,默認優先級是5,優先級最高是10,優先級高的線程被執行的機率高

setDaemon()/isDaemo()//設置和判斷是不是守護線程

currentThread()//靜態函數獲取當前線程

Thread線程主要狀態

(1) New  一旦被實例化以後就處於new狀態

(2) Runnable 調用了start函數以後就處於Runnable狀態

(3) Running 線程被cpu執行 調用run函數以後 就處於Running狀態

 (4)   Blocked 調用join()、sleep()、wait()使線程處於Blocked狀態

 (5)   Dead    線程的run()方法運行完畢或被中斷或被異常退出,線程將會到達Dead狀態

如何中止一個線程

經過上面的函數列表,我能夠知道經過interrupt方法和isInterrupted()方法來中止正在運行的線程,首先必須先讓線程處於阻塞狀態

    /**
     * 銷燬線程方法
     */
    private void destroyThread() {
        try {
            if (null != thread && Thread.State.RUNNABLE == thread .getState()) {
                try {
                    Thread.sleep(500);
                    thread .interrupt();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            thread = null;
        }
    }

Thread線程同步問題

 線程的同步是爲了防止多個線程訪問一個數據對象時,形成數據不一致的問題。

1.)舉例說明:好比多線程操做一個全局變量
    private int count = 100;
    private boolean isRunning = false;
    private void test1() {
        isRunning=true;
        SyncThread syncThread1 = new SyncThread("線程一");
        SyncThread syncThread2 = new SyncThread("線程二");
        SyncThread syncThread3 = new SyncThread("線程三");

        syncThread1.start();
        syncThread2.start();
        syncThread3.start();

    }

    /**
     * 繼承Thread方式
     */
    private class SyncThread extends Thread {

        SyncThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            while (isRunning) {
                count();
            }
        }
    }

未加同步的count函數

    private void count() {
        if (count > 0) {
            Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
        } else {
            isRunning = false;
        }
    }

執行結果:仔細觀察會發現有數據錯亂的現象

添加同步的count函數

    private void count() {
        synchronized (this) {
            if (count > 0) {
                Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
            } else {
                isRunning = false;
            }
        }
    }

執行結果

 2.)線程同步的幾種方式

   一樣仍是以上面的爲例

  (1)同步函數

   private synchronized void count() {
        if (count > 0) {
            Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
        } else {
            isRunning = false;
        }
    }

(2)同步代碼塊 

  private void count() {
        synchronized (this) {
            if (count > 0) {
                Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
            } else {
                isRunning = false;
            }
        }
    }

(3)使用特殊域變量(volatile)實現線程同步

 private volatile int count = 1000;

  a.volatile關鍵字爲域變量的訪問提供了一種免鎖機制,
  b.使用volatile修飾域至關於告訴虛擬機該域可能會被其餘線程更新,
  c.所以每次使用該域就要從新計算,而不是使用寄存器中的值
  d.volatile不會提供任何原子操做,它也不能用來修飾final類型的變量

(4)使用重入鎖實現線程同步

  ReentrantLock() : 建立一個ReentrantLock實例 

  lock() : 得到鎖 

  unlock() : 釋放鎖 
    private void count() {
        lock.lock();
        if (count > 0) {
            Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
        } else {
            isRunning = false;
        }
        lock.unlock();
    }
相關文章
相關標籤/搜索