【JAVA开发小技巧】利用线程池创建多线程,执行并发操作,提高程序运行效率

本文介绍了项目中如何通过线程池并发处理用户搜索记录插入数据库的需求,展示了Runnable接口的实现,并强调了线程安全问题和在高并发场景下使用Redis的注意事项。
摘要由CSDN通过智能技术生成


前言

1.需求场景分析

在项目中,常常可以遇到一些可并发执行的操作,比如要做一个热搜系统,在用户搜索信息的同时,将用户的搜索记录插入到数据库当中;再比如用户在对数据做增删改操作的数据,系统同时记录用户的操作到数据库日志表当中,都是可以并发执行的过程。这时候我们就可以用多线程的方式实现并发,提高程序的运行效率。

2.为什么用线程池

使用线程池实现多线程,最大的原因就是线程池使得程序员可以根据系统的需求和硬件环境灵活的控制线程的数量,且可以对所有线程进行统一的管理和控制,从而提高系统的运行效率,降低系统的运行压力。


一、线程池介绍

线程池中有许多准备运行的线程,每当为线程池提供一个Runnable,就会有一个线程调用run方法。当run方法退出时,这个线程不会死亡,而是留在池中准备为下一个请求提供服务。
执行器(Executors)类有许多静态工厂方法,用来构造线程池,主要包括以下方法:
在这里插入图片描述

二、需求案例与实现

例如,我们实现在用户搜索信息的同时,将用户的搜索记录插入到数据库当中的一个并发需求。

1.任务实现Runnable接口

@Data
@NoArgsConstructor
@AllArgsConstructor
@Slf4j
public class insertRecordTask implements Runnable{
	private TSearch search;
	private TSearchMapper tSearchMapper;
	
	public insertRecordTask(TSearch search, TSearchMapper tSearchMapper){
        this.tSearchMapper = tSearchMapper;
        this.search = search;
    }

	@Override
    public void run() {
    	try{
    	// 这里用MybaytisPlus做插入操作
    		tSearchMapper.insert(search);
    	} catch (Exception e){
            log.info("------------插入搜索记录失败------------");
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}

2.在方法中实现需求

@Service
public class TSearchServiceImpl extends ServiceImpl<TSearchMapper, TSearch> implements TSearchService {
	@Resource
	TSearchMapper tSearchMapper;
	
	// 根据需求选择适当的线程池和线程池大小
	private static final ExecutorService executor = Executors.newFixedThreadPool(2);
	
	public Result searchAndRec(TSearch search){
		// 这里用MybaytisPlus对数据库做查找
		QueryWrapper<TSearch> wrapper = new QueryWrapper<>();
		wrapper.setEntity(search);
		List<TSearch> resultList = baseMapper.selectList(wrapper)
		// 将记录插入数据库的任务提交给线程执行
		insertRecordTask record = new insertRecordTask(search, tSearchMapper);
	    executor.submit(record);
	
		return Result.ok().result(resultList);
	} 
}

三、注意事项

1.线程安全问题

如果方法需要处理高并发场景的需求,且线程之间有共享变量,这种情况下要考虑线程安全问题,处理方法包括在run方法当中加锁等操作。

2.适当使用Redis

本文中展示了一个实现热搜系统的思路,如果系统有高访问量的需求,比如做国内某新闻的热搜排行,那么数据库是很难在短时间内经得起全国大规模用户访问带来的数据量的,所以要做好Redis缓存与数据库的读写同步,并且一定要防止Redis出现雪崩击穿等问题。

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值