重庆微信网站制作公司,农业机械网站模板,酒泉建设厅网站,哈尔滨网站建设推荐SpringBoot使用多线程简单方法#xff1a;地址 线程安全查阅资料参考#xff1a;地址
背景#xff1a; 经过上述资料查看#xff0c;我想写个方法#xff08;依靠notify()唤醒#xff0c;依靠wait()等待#xff09;实现两个线程轮流打印。 实现#xff1a; 1.线程池配…SpringBoot使用多线程简单方法地址 线程安全查阅资料参考地址
背景 经过上述资料查看我想写个方法依靠notify()唤醒依靠wait()等待实现两个线程轮流打印。 实现 1.线程池配置
Configuration
EnableAsync
public class AsyncConfiguration {Bean(ceshiAsync)public Executor doSomethingExecutor() {ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor();// 核心线程数线程池创建时候初始化的线程数executor.setCorePoolSize(3);// 最大线程数线程池最大的线程数只有在缓冲队列满了之后才会申请超过核心线程数的线程executor.setMaxPoolSize(4);// 缓冲队列用来缓冲执行任务的队列executor.setQueueCapacity(10);// 允许线程的空闲时间60秒当超过了核心线程之外的线程在空闲时间到达之后会被销毁executor.setKeepAliveSeconds(6);// 线程池名的前缀设置好了之后可以方便我们定位处理任务所在的线程池executor.setThreadNamePrefix(测试线程-);// 缓冲队列满了之后的拒绝策略由调用线程处理一般是主线程
// executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());executor.initialize();return executor;}}2.轮流打印的方法 两个方法完全一样主要依靠list.notify(); list.wait();
Async(ceshiAsync)public void aaa(ListInteger list) {System.out.println(线程A等待获取i锁);synchronized (list) {try {System.out.println(线程A获取了i锁);while (list.get(0)-1){log.info(线程A:list.get(0));list.set(0,list.get(0)-1);list.notify();list.wait();}} catch (Exception e) {e.printStackTrace();}}}Async(ceshiAsync)public void bbb(ListInteger list) {System.out.println(线程B等待获取i锁);synchronized (list) {try {System.out.println(线程B获取了i锁);while (list.get(0)-1){log.info(线程B:list.get(0));list.set(0,list.get(0)-1);list.notify();list.wait();}} catch (Exception e) {e.printStackTrace();}}}3.调用方法
ListInteger listnew ArrayList();TestGetMapping(value ccc)public void ccc(){list.add(100);ceshiService.aaa(list);System.out.println(-----------);ceshiService.bbb(list);}实现效果 踩坑
1.Async注解未生效 原因测试图方便把注解的方法直接写在方法调用时直接用方法名调用固注解未生效这种写法会导致注解失效例如事务的注解但是与事务不同的时注入自身时记得添加 Lazy注解避免循环依赖。
2.current thread is not owner当前线程不是所有者错误 不要直接用Integer对象当锁查询资料Integer内部的int值是不可改变的估计是值改变时地址变了导致报这个错。
3.执行到一半报错 效果 原因有些测试不适合用Test注解例如这里线程池出问题事后想想这报错完全是理所应当的事情亏我还在怀疑是notify方法提前把锁释放了导致wait执行时没锁了。罪过罪过