1. 程式人生 > >多執行緒基本內容(一)

多執行緒基本內容(一)

一、執行緒建立方式

1、繼承thread類     ①、定義一個執行緒子類     ②、重寫thread的run     ③、例項化一個物件,呼叫star()方法 
public class java_threadone extends Thread {

    public static void main(String[] args){
        (new java_threadone()).start();
        System.out.println("main thread run");
    }

    public synchronized void run(){
        System.out.println("sub thread run");
    }
}
  2、實現runable    實現runable介面的run()方法
public class java_threadtwo implements Runnable {

    public static void main(String[] args){
        (new Thread(new java_threadtwo())).start();
        System.out.println("main thread run");
    }
    public void run() {
        System.out.println("sub thread run");
    }
}
thread與runable的關係:
      class Thread implements Runnable
所以,thread類的run()方法實現runable介面的run()方法,見thread類的原始碼
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
    private Runnable target;

二、執行緒安全—ThreadLocal & synchronized 

1、ThreadLocal

    ThreadLocal類:當多個執行緒使用同一個區域性變數時,ThreadLocal給每個執行緒提供獨立的變數副本,使每個執行緒對自身的副本操作不會影響其他的執行緒所對應的副本,threadlocal通過K(存放執行緒) & Value(存放區域性 變數)的方式包括每個執行緒對應的Value值。-----以空間換時間     該類有四個方法:     set()方法:設定當前執行緒的區域性變數值;原始碼
     public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
     }
    get()方法:返回當前執行緒的區域性變數值;原始碼
     public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }
    remove()方法:將當前執行緒區域性變數的值刪除,目的是減少記憶體的佔用;當執行緒結束後,對應該執行緒的區域性變數將自動被垃圾回收;     initialValue()方法:返回該執行緒區域性變數的初始值,是一個protected方法。

2、synchronized 

    同步鎖,把需要同步的方法或者程式碼塊包裝在它內部,這樣所有執行緒對這塊區域的程式碼訪問必須先持有鎖才能進入,否則攔截在外面等待正在持有鎖的執行緒處理完畢再獲取鎖進入。——以時間換空間
     public void output(String name){
	int len = name.length();
	synchronized (Outputer.class) 
	{
		for(int i=0;i<len;i++){
		   System.out.print(name.charAt(i));
		}
		System.out.println();
	}
     }

3、二者對比

    以空間換時間---為每個執行緒提供一份變數,多開銷記憶體,但是執行緒不用等待,可以一起執行而相互之間沒有影響;     以時間換空間---某個區域的程式碼或者變數只有一份,節省了記憶體,但是會有其他執行緒等待的現象,浪費了時間但是節約了空間;     ThreadLocal比直接使用synchronized同步機制解決執行緒安全問題更簡單,更方便,且結果程式擁有更高的併發 性。