Java 中ThreadLocal类详解
程序员文章站
2024-03-09 10:30:29
threadlocal类,代表一个线程局部变量,通过把数据放在threadlocal中,可以让每个线程创建一个该变量的副本。也可以看成是线程同步的另一种方式吧,通过为每个线...
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中。
上一篇: js笔试题小试牛刀(5)