Scala DynamicVariable替换了ThreadLocal

时间:2016-12-10 10:35:21

标签: java scala thread-local

我不理解DynamicVariable背后的代码和逻辑:

  • 首先使用默认值创建DynamicVariable实例...默认值???你想要每个线程的价值!这是否意味着您可能在所有线程中共享相同的默认值?打败目的......或者?
  • 然后我在所有示例中都看到withValue每次都看起来像创建一个新实例,或者?

e.g。 ThreadLocal有一个有意义的经典案例SimpleDateFormat每次创建都非常昂贵并且它不是线程安全的:

import java.text.SimpleDateFormat;

static ThreadLocal<SimpleDateFormat> dateFormatTl = new ThreadLocal<SimpleDateFormat>();
...
// many threads execute this, check if there already exists a 
// Thread-bound instance otherwise create a new one per-thread
if (dateFormatTl.get() == null) {
  dateFormatTl.set(new SimpleDateFormat("yyyy-dd-MM HH:mm:ss"));
}
// safely use the Thread-bound instance
SimpleDateFormat dateFormat = dateFormatTl.get();
dateFormat.format(new Date(java.util.Date.getTime()));

如何在Scala中复制上述相同的功能并使用DynamicVariable

// create with default instance ... 
// what for? I don't want the same instance shared across all Threads!
val dateFormatDv = new DynamicVariable[SimpleDateFormat](new SimpleDateFormat("yyyy-dd-MM HH:mm:ss"))

// many threads execute this ... 
// I see it is creating one new instance each time, and 
// that is not what I want
 dateFormatDv.withValue(new SimpleDateFormat("yyyy-dd-MM HH:mm:ss")) {
   // safely use the Thread-bound instance, but this is a new one each time arrrggggg
   dateFormatDv.value.format(new Date(java.util.Date.getTime()))
 }

2 个答案:

答案 0 :(得分:1)

你想做的事情可以这样做:

select distinct on (date_trunc('year', date)) t.*
from table_name t
order by date_trunc('year', date),
         abs(date_part('day, (date -
                              (date '2012-02-29' -
                               (extract(year from date '2012-02-29') - extract(year from date)) * interval '1 year'
                               )
                              )
                             )
                      )
            );

至于默认值,它只是让你设置它,以便你可以在没有select distinct on (date_trunc('year', date)) t.* from table_name t order by date_trunc('year', date), abs(date_part('day', date - (date '2012-02-29' - ((extract(year from date '2012-02-29') - extract(year from date)) * interval '1 year') ) ))

的当前线程中方便地使用它
  Future {
    dateFormatDv.withValue(new SimpleDateFormat("yyyy-dd-MM HH:mm:ss")) {
      doStuffWithDateFormat(dateFormatDv.value)
      doMoreStuffWithTheSameFormatInstance(dateFormatDv.value)
    }          
  }

  Future {
    dateFormatDv.withValue(new SimpleDateFormat("yyyy-dd-MM HH:mm:ss")) {
      useADifferentInstanceOfDateFormat(dateFormat.value)
    }
  }

答案 1 :(得分:0)

Scala&#39; ThreadLocal的{​​{1}}更像是我的想法:

DynamicVariable