【Java高并发学习】使用Thread和ForkJoin解决特别消耗时间的操作

new线程来解决特别消耗时间的操作

1.背景

  1. 调用的方法中,存在某一操作特别消耗时间,而又与返回结果关联不大。比如大量发送短信、推送消息等操作。
  2. 进行操作时,附带发送短信而又不过多关注于发送结果。假设发送每条短信操作为0.3s,那么发送几百+的数量,将影响客户操作。
  3. 只需要返回其他操作的结果状态,这时可以另起线程来单独进行发送短信,并直接返回结果。

2.演示模型

大致思路:
  1. 定义方法
  2. 开启线程
  3. 返回状态
  4. 结束线程操作
其他考虑:
  1. 本次演示提供了一个线程来处理循环操作;
  2. 如果在循环中添加线程,会导致线程数量过多,CPU消耗严重;
  3. 在更大操作量情况下,可以使用ForkJoin分而治之进行处理。提供参考代码(新手探索,可能有误哦)。
  4. 其他处理方法暂未想到,待补充完善。
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 {

	private static final long serialVersionUID = 1L;

	private static int HOLD = 300;	//长度超过300,重新分割
	
	private static int count = 0;	//用于记录步骤,便于分析查看
	
	private List v = new ArrayList();
	
	public ForkJoinDemo(List 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 list = new ArrayList();
			//[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 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 v = new ArrayList();
		for(int i = 1; i <= 2000; i++) {
			v.add(String.valueOf(i));
		}
		ForkJoinDemo mt = new ForkJoinDemo(v);
		
		ForkJoinTask submit = pool.submit(mt);
		try {
			String str = submit.get();
			System.out.println("返回结果:"+str);
		} catch (InterruptedException | ExecutionException e) {
			e.printStackTrace();
		}
	}

}



你可能感兴趣的:(Java高并发)