Java 并发编程实践基础 读书笔记: 第二章 构建线程安全应用程序

1,什么是线程安全性?

  简单概括就是一个类在多线程情况下能安全调用就是线程安全

2,Servlet  的线程安全性 

  默认是非线程安全的,写servlet代码的时候需要注意线程安全,注意同步

3,volatile

  volatile实际上是保证了多线程情况下,有读取,有写入,保证了读取的都是最新的值。

  开发中一般boolean值 开关灯用它定义。

  volatile的原理如下:不用volatile修饰的变量再多线程情况下, 每个线程会有一个变量从内存备份放在cpu储存上,每次都是读取这个备份的值

            但是用volatile修饰的变量,强制要求线程每次都存内存读取,一旦一个线程修改了,会立刻更新到内存上,

            同时volatile还有个作用,防止指令重排

4,多线程可能有的问题

  死锁:多个线程竞争共享资源,每个线程都处于堵塞状态,都不结束

  饿死:资源等待时间过长,资源被贪婪线程长期占用不释放,其他线程就处于饿死状态

  活锁:一个线程经常对另一个线程的操作作出响应,如果另一个线程的操作也对这个线程的操作作出响应,那么就可能导致活锁(livelock)。

5.ThreadLocal

  为每一个线程提供一个本地变量,有一个初始值可以定义匿名子类重写,方法名字为initialValue,有set和get方法。

  实现原理为:把当前“线程对象”当作键,变量作为值存储在一个 Map 中

 1     private T setInitialValue() {
 2         T value = initialValue();
 3         Thread t = Thread.currentThread();
 4         ThreadLocalMap map = getMap(t);
 5         if (map != null)
 6             map.set(this, value);
 7         else
 8             createMap(t, value);
 9         return value;
10     }

  同时常见的例子,使用ThreadLoca可以解决simpleDateFormat的多线程安全和资源消耗的问题

 1 package com.peidasoft.dateformat;
 2 
 3 import java.text.DateFormat;
 4 import java.text.ParseException;
 5 import java.text.SimpleDateFormat;
 6 import java.util.Date;
 7 
 8 public class ConcurrentDateUtil {
 9 
10     private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
11         @Override
12         protected DateFormat initialValue() {
13             return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
14         }
15     };
16 
17     public static Date parse(String dateStr) throws ParseException {
18         return threadLocal.get().parse(dateStr);
19     }
20 
21     public static String format(Date date) {
22         return threadLocal.get().format(date);
23     }
24 }

也可以不重写匿名类,获取get的时候判断是不是空

 1 package com.peidasoft.dateformat;
 2 
 3 import java.text.DateFormat;
 4 import java.text.ParseException;
 5 import java.text.SimpleDateFormat;
 6 import java.util.Date;
 7 
 8 public class ThreadLocalDateUtil {
 9     private static final String date_format = "yyyy-MM-dd HH:mm:ss";
10     private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(); 
11  
12     public static DateFormat getDateFormat()   
13     {  
14         DateFormat df = threadLocal.get();  
15         if(df==null){  
16             df = new SimpleDateFormat(date_format);  
17             threadLocal.set(df);  
18         }  
19         return df;  
20     }  
21 
22     public static String formatDate(Date date) throws ParseException {
23         return getDateFormat().format(date);
24     }
25 
26     public static Date parse(String strDate) throws ParseException {
27         return getDateFormat().parse(strDate);
28     }   
29 }
原文地址:https://www.cnblogs.com/haoerlv/p/8487426.html