Java ThreadLocal,javathreadlocal

來源:互聯網
上載者:User

Java ThreadLocal,javathreadlocal

ThreadLocal類,代表一個線程局部變數,通過把資料放在ThreadLocal中,可以讓每個線程建立一個該變數的副本。也可以看成是線程同步的另一種方式吧,通過為每個線程建立一個變數的執行緒區域副本,從而避免並發線程同時讀寫同一個變數資源時的衝突。

樣本如下:

import java.util.Random;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;import com.sun.javafx.webkit.Accessor;public class ThreadLocalTest {    static class ThreadLocalVariableHolder {        private static ThreadLocal<Integer> value = new ThreadLocal<Integer>() {            private Random random = new Random();                        protected synchronized Integer initialValue() {                return random.nextInt(10000);            }        };                public static void increment() {            value.set(value.get() + 1);        }                public static int get() {            return value.get();        }    }        static class Accessor implements Runnable{        private final int id;                public Accessor(int id) {            this.id = id;        }                @Override        public void run() {            while (!Thread.currentThread().isInterrupted()) {                ThreadLocalVariableHolder.increment();                System.out.println(this);                Thread.yield();            }        }                @Override        public String toString() {            return "#" + id + ": " + ThreadLocalVariableHolder.get();        }            }        public static void main(String[] args) {        ExecutorService executorService = Executors.newCachedThreadPool();        for (int i = 0; i < 5; i++) {            executorService.execute(new Accessor(i));        }        try {            TimeUnit.MICROSECONDS.sleep(1);        } catch (InterruptedException e) {            e.printStackTrace();        }        executorService.shutdownNow();    }}

運行結果:

#1: 9685#1: 9686#2: 138#2: 139#2: 140#2: 141#0: 5255。。。

由運行結果可知,各線程都用於各自的Local變數,並各自讀寫互不干擾。

ThreadLocal共提供了三個方法來操作,set,get和remove。

  • 在Android 中的Looper,即使用了ThreadLocal來為每個線程都建立各自獨立的Looper對象。
public final class Looper {    private static final String TAG = "Looper";    // sThreadLocal.get() will return null unless you've called prepare().    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();    private static void prepare(boolean quitAllowed) {        if (sThreadLocal.get() != null) {            throw new RuntimeException("Only one Looper may be created per thread");        }        sThreadLocal.set(new Looper(quitAllowed));    }        。。。}

當某個線程需要自己的Looper及訊息佇列時,就調用Looper.prepare(),它會為線程建立屬於線程的Looper對象及MessageQueue,並將Looper對象儲存在ThreadLocal中。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.