1. 程式人生 > >多執行緒(七):ThreadLocal

多執行緒(七):ThreadLocal

多個執行緒共享同一個物件,所有執行緒都操作同一個物件。

public class ThreadLocalTest {
    public static void main(String[] args) {
        // 三個執行緒每個執行緒列印3次,所以從0列印到9
        IdWorker idWorker = new IdWorker();
        new Thread(new MyRunnable(idWorker, "A")).start();
        new Thread(new MyRunnable(idWorker, "B")).start();
        new
Thread(new MyRunnable(idWorker, "C")).start(); } } class IdWorker { private Long id = 0L; public String generateId(String prefix) { return prefix + (++id); } } class MyRunnable implements Runnable { private IdWorker idWorker; private String prefix; public MyRunnable(IdWorker idWorker, String prefix) { this
.idWorker = idWorker; this.prefix = prefix; } @Override public void run() { for (int i = 0; i < 3; i++) { System.out.println(new Date() + "\t" + Thread.currentThread().getName() + "\t" + idWorker.generateId(prefix)); } } }

這裡寫圖片描述


三個執行緒分別操作各自的物件,每個物件分別列印自己的

public class ThreadLocalTest {
    public static void main(String[] args) {
        // 每個執行緒分別使用各自的IdWorker,所以每個執行緒分別列印自己的0、1、2
        // 要想達到每個執行緒分別使用自己的IdWorker,如果N個執行緒就必須建立N個物件
        IdWorker idWorkerA = new IdWorker();
        IdWorker idWorkerB = new IdWorker();
        IdWorker idWorkerC = new IdWorker();
        new Thread(new MyRunnable(idWorkerA, "A")).start();
        new Thread(new MyRunnable(idWorkerB, "B")).start();
        new Thread(new MyRunnable(idWorkerC, "C")).start();
    }
}

這裡寫圖片描述


ThreadLocal(本地執行緒)將一個變數提供給所有執行緒,所有執行緒各自複製一份到自己的執行緒,每個執行緒持有的物件互不影響。

public class ThreadLocal<T> {
    ThreadLocal.ThreadLocalMap threadLocals = null;

    public ThreadLocal();

    protected T initialValue();

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
   }

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
    public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null) {
                m.remove(this);
         }

   }
   ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
   }

   void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
   }
}
public class ThreadLocalTest {
    public static void main(String[] args) {
        // 只建立一個物件,但是所有執行緒分別複製該物件,每個執行緒分別持有各自的物件
        // 與上一個示例相比,效果相同,但是上個示例建立了N個物件,此示例只建立了一個物件
        IdWorker idWorker = new IdWorker();
        new Thread(new MyRunnable(idWorker, "A")).start();
        new Thread(new MyRunnable(idWorker, "B")).start();
        new Thread(new MyRunnable(idWorker, "C")).start();
    }
}

class IdWorker {
    public static ThreadLocal<Long> threadLocal = new ThreadLocal<Long>() {
        @Override
        protected Long initialValue() {
            return 0L;
        }
    };

    public String generateId(String prefix) {
        long currentId = threadLocal.get() + 1;
        threadLocal.set(currentId);
        return prefix + currentId;
    }
}

class MyRunnable implements Runnable {
    private IdWorker idWorker;
    private String prefix;
    public MyRunnable(IdWorker idWorker, String prefix) {
        this.idWorker = idWorker;
        this.prefix = prefix;
    }

    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println(new Date() + "\t" + Thread.currentThread().getName() + "\t" + idWorker.generateId(prefix));
        }
    }
}

這裡寫圖片描述