前几天空闲时间写了一遍关于平时自己写代码的一些习惯分享了出来,这种文章大家好像挺感兴趣的,还冲到了热榜第三,今天再分享一点哈哈哈
目录
统一管理线程池
有的会在用到多线程的地方就创建一个线程池,为了统一管理,建议建立一个线程池,统一管理,统一设置非核心线程数,拒绝策略等等
扫描二维码关注公众号,回复: 13613699 查看本文章private static volatile ThreadPoolExecutor threadPoolExecutor = null; private static final int CORE_POOL_SIZE = 0; private static final int MAX_MUM_POOL_SIZE = 1000; private static final long KEEP_ALIVE_TIME = 2; private static final TimeUnit UNIT = TimeUnit.MINUTES; private static final int CAPACITY = 1; private static final RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy(); private static final BasicThreadFactory factory = new BasicThreadFactory.Builder().namingPattern("aiserviceplatform-util-thread-pool-%d").build(); private ThreadPoolFactory() { } public static ThreadPoolExecutor getInstance() { if (threadPoolExecutor == null) { synchronized (ThreadPoolFactory.class) { if (threadPoolExecutor == null) { threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_MUM_POOL_SIZE, KEEP_ALIVE_TIME, UNIT, new ArrayBlockingQueue<>(CAPACITY), factory, HANDLER); } } } return threadPoolExecutor; }
大量数据同步
在同步大数据量的信息时,(常用多线程方式:如果表里有唯一索引或者对表进行update操作那么就会经常锁表),优先考虑添加临时表的方式
String realTabelName = ....; String tempTableName = realTableName + "_temp"; createTable(tempTableName); // 创建临时表 boolean flag = sync(tempTableName); // 同步数据 // 根据结果 if(flag) { dropTable(realTabelName); alterTabelName(realTableName, tempTableName); // 临时表改名 实际表 }else { // 同步失败 删除临时表 dropTabel(tempTableName) }
实测:比对一张表做处理会快很多而且不会出问题
接口入参
定义接口的方法时,如接受一个集合类型,尽可能的用Collection<T>,因为其他业务场景可能会穿一个list有的会传一个hashSet,用起来还要改,Map也是。
正栗
Collection<String> getNodeIds(Collection<String> ids);
锁的颗粒度
同步方法直接在方法上加synchronized实现加锁,同步代码块则在方法内部加锁,很明显,同步方法锁的范围比较大,而同步代码块范围要小点,一般同步的范围越大,性能就越差,一般需要加锁进行同步的时候,肯定是范围越小越好,这样性能更好
我一般使用lock:ReentrantLock, ReentrantReadWriteLock,减少锁的颗粒度,提高系统的并发能力。
缓存名称
简短,精练,以文件夹形式保存
xxx:xxx:xxx,以:隔开
方便查看缓存信息
@Cacheable
使用Cacheable做缓存时,也要加上缓存失效时间。
之前提出疑问怎么有的缓存没有失效时间,看代码使用Cacheable缓存的,不会添加就没加(???)。
@Bean public CacheManager cacheManager(RedisConnectionFactory factory) { return new RedisCacheManager( RedisCacheWriter.lockingRedisCacheWriter(factory), this.getRedisCacheConfigurationWithTtl(1), this.getRedisCacheConfigurationMap() ); } private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer hour) { Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); return RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith( RedisSerializationContext .SerializationPair .fromSerializer(jackson2JsonRedisSerializer)).entryTtl(Duration.ofHours(hour)); } public static final String REGION_LIST_BY_CODE_CACHE_KEY = "region:list"; public static final String REGION_NAME_BY_CODE_CACHE_KEY = "region:name"; /** * 已知缓存名称的映射以及用于这些缓存的配置 */ private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() { Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>(); // 自定义缓存名称对应的配置 redisCacheConfigurationMap.put(REGION_LIST_BY_CODE_CACHE_KEY, this.getRedisCacheConfigurationWithTtl(24)); redisCacheConfigurationMap.put(REGION_NAME_BY_CODE_CACHE_KEY, this.getRedisCacheConfigurationWithTtl(120)); redisCacheConfigurationMap.put(RedisKey.MARK_SERVICE_RENEW, this.getRedisCacheConfigurationWithTtl(-1)); redisCacheConfigurationMap.put(RedisKey.MARK_ORGAN_RENEW, this.getRedisCacheConfigurationWithTtl(-1)); redisCacheConfigurationMap.put(RedisKey.MARK_SERVICE_STREAM, this.getRedisCacheConfigurationWithTtl(-1)); redisCacheConfigurationMap.put(RedisKey.MARK_ORGAN_STREAM, this.getRedisCacheConfigurationWithTtl(-1)); return redisCacheConfigurationMap; }
异步任务
为了提高接口的响应速度,我们会把比较耗时的操作异步处理。
例如异步任务,消息队列等。
好了,你们有想知道哪一块儿的可以留言(一时半会不知道该写点啥。。)
嗯。就到这吧。