CountDownLatch 批量更改使用,

代码

复制代码
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.first.pet.platform.entity.PlatformAddress;
import com.first.pet.platform.mapper.PlatformAddressMapper;
import com.first.pet.platform.service.IPlatformAddressServiceTest;
import com.first.pet.threadPool.ThreadPoolUtils;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * <p>
 * 服务类
 * </p>
 *
 * @author yangquan
 * @since 2023-09-26
 */
@Service
public class IPlatformAddressServiceTestImpl extends ServiceImpl<PlatformAddressMapper, PlatformAddress> implements IPlatformAddressServiceTest {

	@Resource
	private PlatformAddressMapper platformAddressMapper;

	//每次查询500条数据操作

	/**
	 * 组装数据
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void assembleAddressData() throws InterruptedException {
		//        1.创建任务计数器  参数为设置任务数量
		//开三个线程,一个线程执行500条
		CountDownLatch countDownLatch = new CountDownLatch(4);

		//        2.开启三个线程  分别执行三个查询
		//        查询 性别信息
		ThreadPoolUtils.sqlThreadPool.submit(new Runnable() {
			@Override
			public void run() {

				QueryWrapper<PlatformAddress> addressWrapper = new QueryWrapper<>();
				addressWrapper.last("limit 1500,500");
				List<PlatformAddress> platformAddresses = platformAddressMapper.selectList(addressWrapper);
				List<PlatformAddress> platformAddress = getPlatformAddress(platformAddresses);

				platformAddressMapper.updateDataById(platformAddress);
				//                得到查询结果
				//                计数器减一
				countDownLatch.countDown();
			}
		});
		//        查询 地区分布
		ThreadPoolUtils.sqlThreadPool.submit(new Runnable() {
			@Override
			public void run() {

				QueryWrapper<PlatformAddress> addressWrapper = new QueryWrapper<>();
				addressWrapper.last("limit 2000,500");
				List<PlatformAddress> platformAddresses = platformAddressMapper.selectList(addressWrapper);
				List<PlatformAddress> platformAddress = getPlatformAddress(platformAddresses);
				platformAddressMapper.updateDataById(platformAddress);


				//                得到查询结果
				//                计数器减一
				countDownLatch.countDown();

			}
		});

		//        查询 注册量
		ThreadPoolUtils.sqlThreadPool.submit(new Runnable() {
			@Override
			public void run() {
				QueryWrapper<PlatformAddress> addressWrapper = new QueryWrapper<>();
				addressWrapper.last("limit 2500,500");
				List<PlatformAddress> platformAddresses = platformAddressMapper.selectList(addressWrapper);
				List<PlatformAddress> platformAddress = getPlatformAddress(platformAddresses);
				platformAddressMapper.updateDataById(platformAddress);

				//                得到查询结果
				//                计数器减一
				countDownLatch.countDown();
			}
		});

		//        查询 注册量
		ThreadPoolUtils.sqlThreadPool.submit(new Runnable() {
			@Override
			public void run() {
				QueryWrapper<PlatformAddress> addressWrapper = new QueryWrapper<>();
				addressWrapper.last("limit 3000,500");
				List<PlatformAddress> platformAddresses = platformAddressMapper.selectList(addressWrapper);
				List<PlatformAddress> platformAddress = getPlatformAddress(platformAddresses);
				platformAddressMapper.updateDataById(platformAddress);

				//                得到查询结果
				//                计数器减一
				countDownLatch.countDown();
			}
		});

		//        await() 当计数器为0的时候 主线程向下执行 没有这一步的话,如果一旦主线程向下执行
		// return map map中可能有的开启的线程还没有执行完毕,即返回的不是线程执行后的结果
		countDownLatch.await();
	}


	private List<PlatformAddress> getPlatformAddress(List<PlatformAddress> platformAddresses) {
		platformAddresses.stream().forEach(e -> {
			e.setInitials(ToFirstChar(e.getAddressName()).toUpperCase());
			e.setCompleteSpelling(ToPinyin(e.getAddressName()));
		});
		return platformAddresses;
	}

	public static void main(String[] args) {
		String ss = ToFirstChar("安徽省");
		System.out.println(ss);
	}


	/**
	 * 获取字符串拼音的第一个字母
	 *
	 * @param chinese
	 * @return
	 */
	public static String ToFirstChar(String chinese) {
		String pinyinStr = "";
//		char[] newChar = chinese.toCharArray();  //转为单个字符
		char[] newChar = new char[]{chinese.toCharArray()[0]};  //转为单个字符
		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		for (int i = 0; i < newChar.length; i++) {
			if (newChar[i] > 128) {
				try {
					pinyinStr += PinyinHelper.toHanyuPinyinStringArray(newChar[i], defaultFormat)[0].charAt(0);
				} catch (BadHanyuPinyinOutputFormatCombination e) {
					e.printStackTrace();
				}
			} else {
				pinyinStr += newChar[i];
			}
		}
		return pinyinStr;
	}

	/**
	 * 汉字转为拼音
	 *
	 * @param chinese
	 * @return
	 */
	public static String ToPinyin(String chinese) {
		String pinyinStr = "";
		char[] newChar = chinese.toCharArray();
		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		for (int i = 0; i < newChar.length; i++) {
			if (newChar[i] > 128) {
				try {
					pinyinStr += PinyinHelper.toHanyuPinyinStringArray(newChar[i], defaultFormat)[0];
				} catch (BadHanyuPinyinOutputFormatCombination e) {
					e.printStackTrace();
				}
			} else {
				pinyinStr += newChar[i];
			}
		}
		return pinyinStr;
	}

}

批量更改数据sql

复制代码
<update id="updateDataById" parameterType="java.util.List">
    <foreach collection="list" item="item" separator=";">
        update platform_address set initials=#{item.initials},complete_Spelling = #{item.completeSpelling}
        where id =#{item.id}
    </foreach>
</update>

数据库连接 必须配置,否则不能批量更改,以下是参考链接

https://blog.csdn.net/carbuser_xl/article/details/127045359

复制代码
 url: jdbc:mysql://rm:5888/first_pet_dev?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false&allowMultiQueries=true

拼音依赖

复制代码
  <dependency>
            <groupId>com.belerweb</groupId>
            <artifactId>pinyin4j</artifactId>
            <version>2.5.0</version>
        </dependency>

线程池工具类

复制代码
import org.apache.tomcat.util.threads.ThreadPoolExecutor;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 描述:
 * 线程池工具类
 * - 所有线程的创建与使用请调用此类的方法
 *
 * @author zhaofeng
 * @date 2023-08-29
 */
public class ThreadPoolUtils {

    /**
     * http异步请求
     * 耗时相对较长,取核心数*2
     * 阻塞时间60秒
     * 空闲时间超过60秒后销毁线程
     */
    public static final ThreadPoolExecutor httpThreadPool = new ThreadPoolImpl(
            8, 16, 60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(1024), new ThreadPoolExecutor.AbortPolicy()
    );

    /**
     * 数据库操作请求
     * 相较http请求耗时较短
     * 取核心线程数*1
     * 阻塞时间60秒
     */
    public static final ThreadPoolExecutor sqlThreadPool = new ThreadPoolImpl(
            4, 8, 60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(1024), new ThreadPoolExecutor.AbortPolicy()
    );

}

汉字转拼音写法,参考链接

复制代码
https://blog.csdn.net/SoumnsJ/article/details/89146371
相关推荐
留不住丨晚霞21 分钟前
说说SpringBoot常用的注解?
java·开发语言
华科云商xiao徐27 分钟前
Java多线程爬虫动态线程管理实现
java·爬虫·数据挖掘
柒七爱吃麻辣烫36 分钟前
八股文系列-----SpringBoot自动配置的流程
java·spring boot·rpc
M1A141 分钟前
Java 面试系列第一弹:基础问题大盘点
java·后端·mysql
发仔12341 分钟前
Dubbo介绍及示例用法
java·dubbo
goxingman1 小时前
关于使用idea打包的时候报错,Maven提示乱码java: �Ҳ�������
java·maven·intellij-idea
邓不利东2 小时前
Spring中过滤器和拦截器的区别及具体实现
java·后端·spring
草履虫建模3 小时前
Redis:高性能内存数据库与缓存利器
java·数据库·spring boot·redis·分布式·mysql·缓存
苹果醋33 小时前
Vue3组合式API应用:状态共享与逻辑复用最佳实践
java·运维·spring boot·mysql·nginx
Micro麦可乐3 小时前
Java常用加密算法详解与实战代码 - 附可直接运行的测试示例
java·开发语言·加密算法·aes加解密·rsa加解密·hash算法