一句话总结volatile、ThreadLocal的作用:
volatile 解决多线程内存不可见性问题,线程变量共享。
ThreadLocal 解决多线程条件下数据隔离问题,每个线程变量复制一个副本。
=================================================================
volatile 可以解决变量同步问题,无法解决线程安全问题,如count++推荐使用:
AtomicInteger count = new AtomicInteger(); count.addAndGet(1); JDK1.8推荐使用LongAdder ,性能更好。
场景:
ThreadLocal dao层会用到,保证每一笔数据库请求都是独立的,互不影响。
SimpleDateFormat 是线程不安全的类,一般不要定义为 static 变量
private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};
并发编程中的三个概念
原子性
一个或多个操作。要么全部执行完成并且执行过程不会被打断,要么不执行。最常见的例子:i++/i--操作。不是原子性操作,如果不做好同步性就容易造成线程安全问题。
可见性
多个线程访问同一个变量,一个线程改变了这个变量的值,其他线程可以立即看到修改的值。可见性的问题,有两种方式保证。一是volatile关键字,二是通过synchronized和lock。
有序性
程序执行的顺序按照代码的先后顺序执行。
ThreadLocal什么时候会出现OOM的情况?为什么?
线程池的一个线程使用完ThreadLocal对象之后,再也不用,由于线程池中的线程不会退出,线程池中的线程的存在,同时ThreadLocal变量也会存在,占用内存!造成OOM溢出!