java多執行緒使用
阿新 • • 發佈:2018-12-12
首先說一下多執行緒的應用場景吧: 比如:迅雷檔案看一個視訊,我們發現進度條顯示不一樣。一個檔案有些地方可以直接看,而前面時間的視訊還可能不能看。 這時候就是用多執行緒,將一個檔案分成多份進行快取,最後再將分割的視訊進行組裝。 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); } }