从头认识多线程-4.3 ThreadLocal使用时需要注意的地方
2016-06-17 15:47
549 查看
4.3 这一章节我们来讨论一下关于ThreadLocal的使用的时候需要注意的地方
ThreadLocal主要的使用是get、set、initialValue这几个方法,具体的使用我们这里不做介绍,下面只是举一些它使用的时候需要注意的地方。1.在get方法的时候出现null
package com.ray.deepintothread.ch04.topic_3; public class ThreadLocalGetNull { private int count = 0; public ThreadLocal<Integer> intThreadLocal = new ThreadLocal<Integer>(); public int getCount() { return intThreadLocal.get(); } public void addCount() { intThreadLocal.set(count++); } public static void main(String[] args) { System.out.println(new ThreadLocalGetNull().getCount()); } }
输出:
Exception in thread “main” java.lang.NullPointerException
at com.ray.deepintothread.ch04.topic_3.ThreadLocalGetNull.getCount(ThreadLocalGetNull.java:10)
at com.ray.deepintothread.ch04.topic_3.ThreadLocalGetNull.main(ThreadLocalGetNull.java:18)
这里直接抛空指针异常,为什么?因为ThreadLocal的实现是通过Map来实现的,我将会在后一章节介绍ThreadLocal的实现原理
对于上面的问题,我们的解决方案是:初始化的时候使用initialValue方法。
package com.ray.deepintothread.ch04.topic_3; public class SolutionOfThreadLocalGetNull { private int count = 0; public ThreadLocal<Integer> intThreadLocal = new ThreadLocal<Integer>() { // 解决办法就是初始化数值 @Override protected Integer initialValue() { return count; } }; public int getCount() { return intThreadLocal.get(); } public void addCount() { intThreadLocal.set(count++); } public static void main(String[] args) { System.out.println(new SolutionOfThreadLocalGetNull().getCount()); } }
输出:
0
在定义ThreadLocal之初就通过initialValue方法初始化返回的值。
2.ThreadLocal大部分的时间是使用在多线程的情况下,需要注意的是,每一个线程都只是使用ThreadLocal标注变量的副本进行计算
代码清单:(这里我沿用上一章节的例子)package com.ray.deepintothread.ch04.topic_3; public class ThreadLocalTest extends Thread { private int count = 0; public ThreadLocal<Integer> intThreadLocal = new ThreadLocal<Integer>() { protected Integer initialValue() { return count; }; }; public int getCount() { return intThreadLocal.get(); } public void addCount() { intThreadLocal.set(count++); } @Override public void run() { try { for (int i = 0; i < 3; i++) { addCount(); System.out.println("Thread[" + getName() + "] count[" + getCount() + "]"); sleep(50); } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { new ThreadLocalTest().start(); Thread.sleep(100); new ThreadLocalTest().start(); Thread.sleep(100); new ThreadLocalTest().start(); } }
输出:
Thread[Thread-0] count[0]
Thread[Thread-0] count[1]
Thread[Thread-1] count[0]
Thread[Thread-0] count[2]
Thread[Thread-1] count[1]
Thread[Thread-1] count[2]
Thread[Thread-2] count[0]
Thread[Thread-2] count[1]
Thread[Thread-2] count[2]
从输出我们可以看到,每一个线程操作的count的数值都是独立的,不被其他线程影响。
总结:这一章节我们讨论了ThreadLocal使用的两个注意的地方。
这一章节就到这里,谢谢
我的github:https://github.com/raylee2015/DeepIntoThread
目录:http://blog.csdn.net/raylee2007/article/details/51204573
相关文章推荐
- UML图详解(九)包图
- iOS大神牛人的博客集合
- Oracle备份与恢复案例
- BroadCast两种实现方式
- Android中的IPC方式——使用AIDL
- [PHP] - Laravel - CSRF token禁用方法
- 利用PCA来简化数据
- 【操作系统】实验四 主存空间的分配和回收
- windows server 2003 AD
- linux多线程编程中用到的函数和类型
- 自然数与自然数的五个公理
- FreeMarker的认识及实例(二)
- Head_First设计模式(二)----观察者模式
- Maven学习篇(一)---快速入门
- HighCharts趋势图动态设置Series数组(根据后台决定具体几个data), 并动态刷新数据
- Android gallery 实现定时滑动并添加动画效果
- 补、C++第八次作业
- Android RecyclerView 使用完全解析 体验艺术般的控件
- css display:table-cell 文字、图片的垂直水平居中
- android接收系统广播