版权声明:不要随便复制~~ 技术更新有些东西也会相应更新 https://blog.csdn.net/chuxin_mm/article/details/84955411
首先说一下多线程的应用场景吧:
比如:迅雷文件看一个视频,我们发现进度条显示不一样。一个文件有些地方可以直接看,而前面时间的视频还可能不能看。
这时候就是用多线程,将一个文件分成多份进行缓存,最后再将分割的视频进行组装。
eg:
1+2+3+..+1亿;(最开始测试用的是1兆,但是超过了double的范围,计算的数据不准确,用bigdecimal太麻烦了)
如何快速运算出数据结果 ?
常规算法:
public static void main(String[] args) {
long sum = 0L;
for (long i = 1L; i <= 100000000L; i++) {
sum += i;
}
System.out.println("1到1亿累加的和为:" + sum);
}
上面这一段代码确实可以计算出数据最后的和: 5000000050000000。
但是呢 ? 速度太慢了。
这时候就可以用多线程。
上面的代码用的是1个线程执行,需要时间大约30毫秒。
如果同时开10个线程,时间就会大大缩短近6倍。
先不用线程池吧,创建线程有3种方式,测试这个必须用第3种方式,因为多线程只有Callable<T>有返回值:
多线程算法:
1. 先创建一个多线程运行的类
public class Sum implements Callable<List> {
private long min;
private long max;
public Sum(long min, long max) {
this.min = min;
this.max = max;
}
@Override
public List call() throws Exception {
long l = System.currentTimeMillis();
long sum = 0;
for (long i = min; i <= max; i++) {
sum += i;
}
long e = System.currentTimeMillis();
long time = e - l;
// 将求和数据 与 求和时间 封装到list集合。
ArrayList arrayList = new ArrayList();
arrayList.add(sum);
arrayList.add(time);
System.out.println("sum = " + sum);
return arrayList;
}
}
2. 创建10个多线程
public class TestOne {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建带有10个线程的线程池
ExecutorService pool = Executors.newFixedThreadPool(10);
long max = 100000000L;
int d = 10; // 创建10个线程
assert max >d; // 断言,等同于这个意思: if (max <= d) throw new AssertionError();
long sp = max /10;
List<Future<List>> fs = new ArrayList<>();
for (int i = 1; i <= d; i++) {
if (i < d) {
fs.add(pool.submit(new Sum(1 + (i - 1) * sp, i * sp)));
} else {
fs.add(pool.submit(new Sum(1 + (i - 1) * sp, max)));
}
}
long s = 0, t = 0;
for (Future<List> f : fs) {
List list = f.get();
s += (long) list.get(0);
t += (long) list.get(1);
}
pool.shutdown();
// 这个时间不是很准确,但是计算时间,确实比单线程更快
System.out.println("求和:" + s + ",求和时间:" + t/d);
}
}