面试十二、ThreadLocal使用
1、使用场景
1.1、静态变量如果要考虑线程安全的情况。用作保存每个线程自身的独享对象,以保证线程安全
如下代码:结果报异常了,因为sdf线程不安全,导致部分线程获取的时间不对
// 时间工具 public class DateUtil { private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public static Date parse(String dateStr) { Date date = null; try { date = sdf.parse(dateStr); } catch (ParseException e) { e.printStackTrace(); } return date; } } // 调用 public static void main(String[] args) { ExecutorService service = Executors.newFixedThreadPool(20); for (int i = 0; i < 20; i++) { service.execute(()->{ System.out.println(DateUtil.parse("2019-06-01 16:34:30")); }); } service.shutdown(); }
解决方案一:每次新new对象(下第一个类),开销太大
解决方案二:加锁,并发上不去
解决方案三:使用treadLocal
1 public class DateUtil { 2 3 public static Date parse(String dateStr) { 4 SimpleDateFormat sdf = 5 new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 6 Date date = null; 7 try { 8 date = sdf.parse(dateStr); 9 } catch (ParseException e) { 10 e.printStackTrace(); 11 } 12 return date; 13 } 14 } 15 16 public class DateUtil { 17 18 private static final SimpleDateFormat sdf = 19 new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 20 21 public static synchronized Date parse(String dateStr) { 22 Date date = null; 23 try { 24 date = sdf.parse(dateStr); 25 } catch (ParseException e) { 26 e.printStackTrace(); 27 } 28 return date; 29 } 30 } 31 32 public class DateUtil { 33 34 private static ThreadLocal<DateFormat> threadLocal = ThreadLocal.withInitial( 35 ()-> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); 36 37 public static Date parse(String dateStr) { 38 Date date = null; 39 try { 40 date = threadLocal.get().parse(dateStr); 41 } catch (ParseException e) { 42 e.printStackTrace(); 43 } 44 return date; 45 } 46 }
1.2、用作每个线程内需要保存的独立信息,以便其他地方用到时可直接获取避免传参,类似上下文
2、使用注意
内存泄漏,记得每次使用完都remove
posted on 2021-08-26 23:34 Iversonstear 阅读(37) 评论(0) 编辑 收藏 举报