做印刷在哪个网站接单好好/站长工具使用
问题:ssm框架,spring中controller和service都是单例的,那是怎么保证线程安全呢?
通过threadLocal保证,
实际一个实例,tomcat中线程池执行任务时,获取单例的副本,每个线程的执行都是操作单例的副本
那既然有单例的副本,此时还是单例的吗?????
https://www.cnblogs.com/-zhuang/articles/10607877.html
所有线程共享
类中定义 :static DateFormat ;
线程内共享:
类中定义-此时每个线程内部有一个新的对象,线程内部单独有一个对象,不存在线程安全的问题
private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() ;
方法内共享:
方法内声明 DateFormat format;
说明:使用 ThreadLocal, 也是将共享变量变为独享,线程独享肯定能比方法独享在并发环境中能减少不少创建对象的开销。如果对性能要求比较高的情况下,一般推荐使用这种方法。
思路:
controller中service并行调用 service中的慢方法:
controller中 线程池
实现callable的实现类,直接将controller中的service和参数传入
线程池submit
future.get获取返回内容实例:
@Controller
@RequestMapping(value = "")
public class ReportSetController {static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(ReportSetController.class);static ExecutorService pool = Executors.newFixedThreadPool(10);@AutowiredOrganizationService organizationService;@RequestMapping(value="/reportset/toEdit.action")public String toEdit( ModelMap modelMap,ServletRequest request,String reportsetIdStr ){// 预处理 。。。 省略// 老的写法如下:串行调用// String treecontent1 = JSON.toJSONString(treeService.getOrganTree(ReportsetUserType.TO, reportsetId));// 新的写法如下: 并行调用,开启新的线程Future<String> submit = pool.submit(new TreeContentTask(treeService, ReportsetUserType.TO, reportsetId));String str = reportsetService.getReportsetBoardStrList(reportsetId);List<DashboardBoard> dashboardBoards = dashboardService.listUserDashboards(RSBIUtils.getLoginUserInfo().getUserId());String treecontent = null;try {treecontent = submit.get();} catch (InterruptedException e) {logger.error("组织关系获取失败", e);} catch (ExecutionException e) {logger.error("组织关系获取失败", e);}modelMap.put("treecontent", treecontent);return "reportset/reportset-edit";}
}public class TreeContentTask implements Callable<String> {OrganizationTreeService service ;ReportsetUserType type;Integer reportsetId;// 有线程安全问题?同一个servicepublic TreeContentTask(OrganizationTreeService service, ReportsetUserType type, Integer reportsetId){this.service = service;this.type = type;this.reportsetId = reportsetId;}@Overridepublic String call() throws Exception {OrganTreeCoreDto organTree = service.getOrganTree(type, reportsetId);return JSON.toJSONString(organTree);}
}
网上怎么解决的?
controller中创建任务 线程池在service中
https://blog.csdn.net/Hello_Ray/article/details/83340064
微服务优化之并行调用
https://blog.csdn.net/tidu2chengfo/article/details/80275064