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
相关推荐
Y学院1 天前
Spring AI Alibaba 高质量实战教程(从入门到企业级落地)
java·人工智能·spring·自然语言处理
水木流年追梦1 天前
CodeTop Top 300 热门题目3-字符串相加
java·前端·算法
编程之升级打怪1 天前
自定义实现Java的HashMap集合
java·开发语言
后端AI实验室1 天前
我带的那个实习生,比我更依赖AI——但他的问题和我完全不同
java·ai
y小花1 天前
安卓StorageManagerService
android·java
码王吴彦祖1 天前
AI 逆向分析国航 AirChina FECU 参数来源并实现离线生成
android·java·javascript
LJianK11 天前
进程、线程、多线程、异步
java·开发语言·jvm
ch.ju1 天前
Java程序设计(第3版)第二章——循环结构1
java
大黄烽1 天前
IDEA中集成AI 工具CodeBuddy和Trae区别和选型
java·人工智能·intellij-idea
HalvmånEver1 天前
MySQL表的约束(二)
java·数据库·mysql