多线程及线程池解析

1.Volatile解决了多线程可见性问题和重排序问题。

2.可见性问题:jmm内存模型,当主线程的本地内存修改后,会及时更新到主内存中,其他的子线会在主内存及时更新

3.重排序:单线程环境下,不考虑重排序问题,多线程环境下,重排序会导致线程安全问题。

4.当需要停止一个线程时,thread自身的.stop方法已经过时,在执行stop方法时,如果停止主线程,子线程也无法执行;可以采用while循环去处理,将子线程放在while循环中,循环条件默认为flag=true,当子线程执行完毕后,将flag设置为false,退出循环。

5.原子性问题解决方案:首先,volatile不能解决原子性问题,被访问的资源必须是static静态的共享资源,否则不能被多个线程调用,解决原子性的可以通过悲观锁如synchronized在方法上加锁实现原子性,也可以用过乐观锁 version版本号去解决,也可以通过atomicInteger原子类去解决原子性问题。

6.并发队列:分为阻塞队列和非阻塞队列。

7.阻塞队列常用的是:数组和链表的阻塞队列,底层是带lock锁的,确保并发线程的安全问题。

8.非阻塞队列的是,concurrentLinkedQuene 用.offer去实现队列的先进先出方式;如果入队的时候队列满了,我们就指定等待时间,进入阻塞状态。

9.为什么使用线程池:

每次创建线程的时候,我们都要去new Thread().start(),造成资源消耗,也不利于管理。所以我们通过创建线程池的ThreadPoolExcutor核心类去实现线程池,以应对多线程并发环境

10.线程池底层原理:

当我们提交任务时,会先将线程数量和核心线程数量进行比较,如果线程数量小,那么就会创建一个新的线程来执行任务。执行后,线程不会关闭,会从阻塞队列里去拿新的任务执行,重复以上操作。如果阻塞队列里没有新的任务,就会等新的任务进来后,再次提交,知道线程数量等于核心线程数量时,如果再提交任务,就会把新的任务放在其他队列里,直到核心线程池执行完其他任务时,再执行其他队列的任务。

11.线程池的核心参数:

核心线程的大小,最大线程的大小,空闲线程存活时间,消亡时间单位,等待执行的线程的工作队列,创建线程的工厂

12.线上突然宕机怎么处理

在提交任务的时候,在数据库存储提交任务的状态,未提交,已提交,已完成。待系统重启后,读取数据库状态为未完成的线程,在重新提交到线程池中。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
对于Java多线解析Excel,你可以使用Apache POI库来操作Excel文件。下面是一个简单的示例代码,演示了如何使用多线解析Excel文件: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.File; import java.io.FileInputStream; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ExcelParser { private static final int THREAD_COUNT = 4; // 线程数 public static void main(String[] args) { File file = new File("path_to_excel_file.xlsx"); try (FileInputStream fis = new FileInputStream(file); Workbook workbook = new XSSFWorkbook(fis)) { Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表 int rowCount = sheet.getLastRowNum() - sheet.getFirstRowNum(); // 每个线程处理的行数 int batchSize = rowCount / THREAD_COUNT; ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT); List<Runnable> tasks = new ArrayList<>(); for (int i = 0; i < THREAD_COUNT; i++) { int startRow = i * batchSize + 1; int endRow = (i == THREAD_COUNT - 1) ? rowCount : startRow + batchSize - 1; tasks.add(() -> { for (int j = startRow; j <= endRow; j++) { Row row = sheet.getRow(j); // 解析行数据 // TODO: 根据需要处理每行的数据 } }); } executor.invokeAll(tasks); executor.shutdown(); } catch (Exception e) { e.printStackTrace(); } } } ``` 这个示例代码使用了`ExecutorService`来创建一个固定大小的线程池,并将Excel文件的行分配给不同的线程进行处理。你可以根据需要在`// TODO`的部分添加适当的代码来处理每行的数据。 请注意,这只是一个简单的示例,实际应用中可能需要更复杂的逻辑来解析Excel文件。此外,还应该注意线程安全性和性能问题,确保多线程操作不会导致数据错误或资源竞争。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值