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);

 

posted @ 2020-09-07 15:33  PEAR2020  阅读(1228)  评论(0编辑  收藏  举报