1:引用传递,创建一个变量,给两个线程都传递进去。
2:静态修饰 static 通过该修饰符说明,该变量只有一份, 所有线程共用一份。
例如下面的htmlidMap通过static变量修饰,
updateCount能够得到queryNews 修改htmlidMap之后的值。
如果不用static修饰,那么每个线程是使用不同的htmlidMap。
// @Autowired static LinkedHashMap<Long, Integer> htmlidMap =new LinkedHashMap<>(); public void updateCount() { ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1); //指定线程个数 scheduledExecutorService.scheduleAtFixedRate(new Runnable() { //以固定频率执行,线程1 @Override public void run() { System.out.println(Thread.currentThread() + "开启了" + System.currentTimeMillis() + "size" + htmlidMap.size()); } }, 10, 10, TimeUnit.SECONDS); } @RequestMapping("/queryNews") public String queryNews(Model model, long htmlid) { News news = foreService.queryNews(htmlid); //查询新闻 int count = news.getCount(); Integer newCount = 0; htmlidMap.putIfAbsent(htmlid, count); //添加 newCount = htmlidMap.computeIfPresent(htmlid, (key, value) -> { htmlidMap.remove(htmlid);//删除, return value + 1; }); htmlidMap.putIfAbsent(htmlid, newCount); //添加 // foreService.updateCount(htmlid, newCount); news.setCount(newCount); model.addAttribute("response", news); return "front/news_content"; }
static和volatile的区别
参考http://blog.sina.com.cn/s/blog_4e1e357d0101i486.html
1. volatile是告诉编译器,每次取这个变量的值都需要从主存中取,而不是用自己线程工作内存中的缓存.
2. static 是说这个变量,在主存中所有此类的实例用的是同一份,各个线程创建时需要从主存同一个位置拷贝到自己工作内存中去(而不是拷贝此类不同实例中的这个变量的值),也就是说只能保证线程创建时,变量的值是相同来源的,运行时还是使用各自工作内存中的值,依然会有不同步的问题.