new线程来解决特别消耗时间的操作
1.背景
- 调用的方法中,存在某一操作特别消耗时间,而又与返回结果关联不大。比如大量发送短信、推送消息等操作。
- 进行操作时,附带发送短信而又不过多关注于发送结果。假设发送每条短信操作为0.3s,那么发送几百+的数量,将影响客户操作。
- 只需要返回其他操作的结果状态,这时可以另起线程来单独进行发送短信,并直接返回结果。
2.演示模型
大致思路:
- 定义方法
- 开启线程
- 返回状态
- 结束线程操作
其他考虑:
- 本次演示提供了一个线程来处理循环操作;
- 如果在循环中添加线程,会导致线程数量过多,CPU消耗严重;
- 在更大操作量情况下,可以使用ForkJoin分而治之进行处理。提供参考代码(新手探索,可能有误哦)。
- 其他处理方法暂未想到,待补充完善。
package demo;
/**
* @author wsz
* @date 2018年1月5日
*/
public class Demo {
public void longTime() {
//doSomething
//发送短信
System.out.println("方法开始执行:"+System.currentTimeMillis());
new Thread() {
public void run() {
System.out.println("开始发送短信:"+System.currentTimeMillis());
for(int i = 0; i < 300; i++) {
try {
Thread.sleep(100);//模拟发送短信的耗时
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("发送短信结束:"+System.currentTimeMillis());
}
}.start();
System.out.println("方法结束时间:"+System.currentTimeMillis());
}
public static void main(String[] args) {
Demo demo = new Demo();
demo.longTime();
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
/**
* 采用ForkJoin分而治之方法,把大数据量进行隔离处理
* @author wsz
* @date 2018年1月5日21:28:20
*/
public class ForkJoinDemo extends RecursiveTask<String> {
private static final long serialVersionUID = 1L;
private static int HOLD = 300; //长度超过300,重新分割
private static int count = 0; //用于记录步骤,便于分析查看
private List<String> v = new ArrayList<String>();
public ForkJoinDemo(List<String> v) {
super();
this.v = v;
}
@Override
protected String compute() {
count++;
int size = v.size();
System.out.println(count+" "+v.get(0)+" "+v.get(size-1)); //第几步+开始数字+结束数字
boolean isOk = size < HOLD;
String res = "1";
if(isOk) {
//doSomething
}else {
int step = size / 4; //分割4份
List<ForkJoinDemo> list = new ArrayList<ForkJoinDemo>();
//[1,2000)
//[1,500] 继续分割 4份
//[501,1000]
//[1001,1500]
//[1501,2000]
for(int i = 0; i < 4; i++) {
int start = i*step;
int end = start+step;
if(end >= size) end = size;
List<String> subList = v.subList(start, end);
ForkJoinDemo multiThread = new ForkJoinDemo(subList);
list.add(multiThread);
multiThread.fork();
}
for (ForkJoinDemo mt : list) {
String join = mt.join();
if("0".equals(join)) {
res = "0";
break;
}
}
}
return res;
}
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
List<String> v = new ArrayList<String>();
for(int i = 1; i <= 2000; i++) {
v.add(String.valueOf(i));
}
ForkJoinDemo mt = new ForkJoinDemo(v);
ForkJoinTask<String> submit = pool.submit(mt);
try {
String str = submit.get();
System.out.println("返回结果:"+str);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}