Java 之 應用多線程計算1+2+...+100之多種方法比較(一)


一、思路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);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM