一、思路1: 不使用線程池
1.run方法
定義 static int[] arr = new int[10];
將1~100 分成10個數組,分成10個線程的run()方法分別計算
其中每個線程的run方法拿到一個ix下標當作自己的數組索引
方法1:0 -> 1~10 ; 1 -> 11~20 ; 9 -> 91~100
static void call1(int ix){ int sum = 0; // 0 -> 1~10 ; 1 -> 11~20 ; 9 -> 91~100 for (int i = ix*10+1; i <= (ix+1)*10 ; i++) { sum += i; } arr[ix] = sum; System.out.println(Thread.currentThread().getName()+"\t"+sum); }
方法2: 循環基礎:i -> 0,10,20,30,40,50,60,70,80,90
i+ix: 0~90;1~91;... 9~99
i+ix+1: 1~91; 2~92;... 10~100
static void call2(int ix){ int sum = 0; // ix // 0 -> 0,10,20,30,40,50,60,70,80,90 // 1 -> 0+1=1,10+1=11,21,31 ... 91 // ... // 9 -> 9,19,29,39 ... 99 // i 從 0,10,20,30,40,50,60,70,80,90 for (int i = 0; i < 100 ; i+=10) { // sum += i+ix; // 0~90;1~91;... 9~99; sum += i+ix+1; // 1~91; 2~92;... 10~100; } arr[ix] = sum; a++; System.out.println(Thread.currentThread().getName()+"\t"+sum); }
2.可執行的 Runnable target
static class Sum implements Runnable{ // 下標ix private int ix; public Sum(int ix){ this.ix = ix; } @Override public void run() { call2(ix); // call1(ix); } }
3.mian方法測試代碼
// 順序執行,沒有並發 -> 解決辦法 -> 加狀態值a Thread[] th = new Thread[10]; for (int i = 0; i < th.length; i++) { th[i] = new Thread(new Sum(i)); th[i].start();
th[i].join(); // Waits for this thread to die. }
int sum = 0;
for (int i = 0; i <arr.length ; i++) {
sum +=arr[i];
}
System.out.println("sum all\t"+sum);
運行結果:thread1,2,3,4,...順序執行
優化:1)屬性中增加 static int a = 0; // 狀態值
2)main方法中增加狀態值的判斷:
二、思路2:使用線程池,不需要聲明arr數組
1.run()方法:
static int _call2(int ix){ int sum = 0; for (int i = 0; i < 100 ; i+=10) { sum += i+1+ix; System.out.println(Thread.currentThread().getName()+"\t"+sum); } return sum; }
2.main方法中直接執行帶返回值的submit
ExecutorService service = Executors.newFixedThreadPool(10); // 順序執行,沒有並發 for (int j = 0; j < arr.length; j++) { final int _j = j; arr[j] = service.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { // 從線程外向里面傳值只能是常量 return _call2(_j); } }).get(); }
int sum = 0;
for (int i = 0; i <arr.length ; i++) {
sum +=arr[i];
}
System.out.println("sum all\t"+sum);
缺陷:一個一個把返回值塞進arr[i]中,沒有並發,依然順序
優化:1)不需要線程的get()返回值,直接放進屬性中的arr[i]
2) 使用狀態值a
// 線程池 + 並發 for (int j = 0; j <arr.length ; j++) { service.submit(new Sum(j)); } while (a<10){ Thread.sleep(100); } int sum = 0; for (int i = 0; i <arr.length ; i++) { sum +=arr[i]; } System.out.println("sum all\t"+sum);