zoukankan      html  css  js  c++  java
  • 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()+"	"+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()+"	"+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 "+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()+"	"+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 "+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	"+sum);
  • 相关阅读:
    UVA1349 Optimal Bus Route Design 最优巴士路线设计
    POJ3565 Ants 蚂蚁(NEERC 2008)
    UVA1663 Purifying Machine 净化器
    UVa11996 Jewel Magic 魔法珠宝
    NEERC2003 Jurassic Remains 侏罗纪
    UVA11895 Honorary Tickets
    gdb调试coredump(使用篇)
    使用 MegaCLI 检测磁盘状态并更换磁盘
    员工直接坦诚直来直去 真性情
    山东浪潮超越3B4000申泰RM5120-L
  • 原文地址:https://www.cnblogs.com/sabertobih/p/13627214.html
Copyright © 2011-2022 走看看