阿飞飞飞

学而时习之

导航

线程并发的两种方式

例子:1-100累加,10条线程并发

一、Thread

首先定义数组长度为10

并定义一个状态值

这里定下每个数组的长度为10,后面开10条线程,最后得出结果

    static int[] arr = new int[10];
    static int i = 0;

 

关于数组的两种累加方式

1.步幅为1的累加方式 2.设置步幅为10,个位数相同的累加

    static void cal1(int ix){
        int sum = 0;
        for (int i = ix*10+1; i <=(ix+1)*10; i++) {
            sum += i;
        }
        arr[ix] = sum;//记录每个数组内的和
        i++;//作为状态值
        System.out.println(Thread.currentThread().getName()+"\t"+sum);
    }

    static void cal2(int ix){
        int sum = 0;
        for (int i = 0; i <100 ; i+=10) {
            sum += i+ix+1;
        }
        arr[ix] = sum;
        i++;
        System.out.println(Thread.currentThread().getName()+"\t"+sum);
    }

 

写出一个类来实现Runnable接口,重写runnable方法

static class Sum implements Runnable{
        private int ix;//定义ix作为cel内方法数组的下标

        public Sum(int ix){
            this.ix = ix;
        }

        @Override
        public void run() {
            cal1(ix);
        }
    }

 

写测试类,定义10条线程,若需要达到并发的效果,状态值将会起到作用

public static void main(String[] args) throws InterruptedException {
        Thread[] ths = new Thread[10];
        for (int i = 0; i < ths.length; i++) {
            ths[i] = new Thread(new Sum(i));
            ths[i].start();
            //ths[i].join(); wait for this thread to die 多线程 但是没有并发
        }
     //只要定义的状态值没有达到要求,就不能执行下一步
        while (i<10){
            Thread.sleep(1000);
        }

        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];//将每个数组内的和再一次求和,得到结果
        }
        System.out.println("sum all\t"+sum);
        结果如下:
                Thread-2    255
                Thread-1    155
                Thread-3    355
                Thread-0    55
                Thread-6    655
                Thread-5    555
                Thread-4    455
                Thread-7    755
                Thread-9    955
                Thread-8    855
                sum all    5050

 

 

二、线程池解决并发

在测试类,可以使用固定线程池,定义10条线程

1.考虑不并发的情况,即需要前一条线程执行完毕才能开启下一条线程

两个小知识点:线程外往内部类传值,不能是变量

       submit()方法通常配合callable使用,同时有返回值

     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 cal2(_j); //线程外往内部类里面传值,只能是常量
                }
            }).get();
        }
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        System.out.println("sum all\t"+sum);

 

 

2.考虑并发的情况,多线程并行

在submit()方法内new 出实现Runnable()接口的实现类

    ExecutorService service = Executors.newFixedThreadPool(10);
        //并发
        for (int j = 0; j < arr.length; j++) {
        service.submit(new Sum(j));
        }
        //状态值满足则进行下一步
        while (i<10){
        Thread.sleep(1000);
        }
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
        sum += arr[i];
        }
        System.out.println("sum all\t"+sum);
        //结果如下:
                pool-1-thread-1    55
                pool-1-thread-2    155
                pool-1-thread-7    655
                pool-1-thread-4    355
                pool-1-thread-9    855
                pool-1-thread-3    255
                pool-1-thread-6    555
                pool-1-thread-8    755
                pool-1-thread-10    955
                pool-1-thread-5    455
                sum all    5050

 

posted on 2020-09-07 23:26  阿飞飞飞  阅读(382)  评论(0编辑  收藏  举报