搜索
写经验 领红包
 > 育儿

线程如何使用(线程实现的三种方法)

导语:线程策略之我们该怎么合理使用

我们都知道线程的4种丢弃策略,但是有时候会为了选择哪种策略犯了难,

下面我按照自己的理解给大家白话一下:

4种线程丢弃策略:

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。

ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务

ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务

1.应用场景1

线程可以忽略,例如做一些宽泛统计,例如登录人数等

这个时候我们可以选择DiscardPolicy或者DiscardOldestPolicy

2.应用场景2

线程必须执行,否则抛出异常,这个时候我们可以选择AbortPolicy,

这种场景说实话比较少,一般我们想执行,肯定是要执行完的,而不是终止线程

3.应用场景3

线程必须执行,如果线程数和队列都满的情况下,我们交给主线程执行

这种情况的坏处是,很容易cpu飚的过高,或者直接内存溢出

重点来了,现实情况下我们执行多线程任务是希望我们的任务

像流水一样执行,不是太慢,也不是太快,例如我们执行读取文件,

多线程处理然后入库,我们都知道读取文件的速度是非常快的,而处理

入库是非常慢:

代码如下:

File file=new File(&34;);

FileInputStream fis = new FileInputStream(file);

BufferedReader br=new BufferedReader(new InputStreamReader(fis));

while ((line = br.readLine()) != null) {

//threadPoolExecutor自定义线程池,我们的抛弃策略选择的是CallerRunsPolicy

//SyncDataCallable我们实现了Callable接口的线程

threadPoolExecutor.submit(new SyncDataCallable(line));

}

我们知道while其实是非常快,如果我们的代码真的这样跑的话,

环境基本上直接就瘫痪了,这个时候怎么办呢?

其实我们可以通过读取线程的执行状态来判断存活的线程,

如果线程在一定数量之外,我们可以让主线程sleep一下,等待子线程执行完,

然后再继续往我们的线程池里面扔任务

示例如下:

List<Future<String>> futureList=new Vector<>();

while ((line = br.readLine()) != null) {

//当线程数量超过10的时候,这里面执行清空futureList

if (futureList.size() > 10) {

removeFuture(futureList);

}

Future<String> future = threadPoolExecutor.submit(new SyncDataCallable(line));

futureList.add(future);

}

//移除isDone完成的线程

public void removeFuture(List<Future<String>> futureList) throws InterruptedException {

if(null!=futureList){

Thread.sleep(200L);

List<Future<String>> removeFutures=new Vector<>();

futureList.forEach(future -> {

if(future.isDone()) {

removeFutures.add(future);

}

});

removeFutures.forEach(future -> {

futureList.remove(future);

});

}

}

小伙伴们,你们get到了吗?

欢迎指正,或者有更好的方法提出来!

本文内容由小里整理编辑!