问题:多线程计算1+2+…+100,如:起四个线程,分别计算1+2+..25, 26+27+…+50, 51+52+…+75, 76+77+…100, 最后将总和相关,输出应为5050
解决方法:

  • 依次调用thread.join(),主线程输出结果。注意:sum为共享变量,访问共享变量时,用synchronized同步
  • 使用countDownLatch, 子线程执行完调用 countdownlatch.countdown(),主线程调用countdownlatc.await() 等待子线程执行完成,输出结果。 注意:sum为共享变量,访问共享变量时,用synchronized同步
  • 使用cyclicbarrier, 子线程执行完调用 cyclicbarrier.await(), 最后都到达barrier时,输出结果。注意:sum为共享变量,访问共享变量时,用synchronized同步
  • 通过线程池管理线程,用Future取得各子线程执行结果,最后将结果相加。

使用thread.join

依次调用thread.join(),主线程输出结果。注意:sum为共享变量,访问共享变量时,用synchronized同步。代码如下:

package thread;

public class ThreadAdd {
    public static int sum = 0;
    public static Object LOCK = new Object();


    public static void main(String[] args) throws InterruptedException {
        ThreadAdd add = new ThreadAdd();
        ThreadTest thread1 = add.new ThreadTest(1, 25);
        ThreadTest thread2 = add.new ThreadTest(26, 50);
        ThreadTest thread3 = add.new ThreadTest(51, 75);
        ThreadTest thread4 = add.new ThreadTest(76, 100);
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

         thread1.join();
         thread2.join();
         thread3.join();
         thread4.join();
         System.out.println("total result: "+sum);
    }

    class ThreadTest extends Thread {
        private int begin;
        private int end;

        @Override
        public void run() {
            synchronized (LOCK) {
                for (int i = begin; i <= end; i++) {
                    sum += i;
                }
                System.out.println("from "+Thread.currentThread().getName()+" sum="+sum);
            }
        }

        public ThreadTest(int begin, int end) {
            this.begin = begin;
            this.end = end;
        }
    }
}

输出:
from Thread-0 sum=325
from Thread-1 sum=1275
from Thread-2 sum=2850
from Thread-3 sum=5050
total result: 5050

使用countDownLatch

子线程执行完调用 countdownlatch.countdown(),主线程调用countdownlatc.await() 等待子线程执行完成,输出结果。 注意:sum为共享变量,访问共享变量时,用synchronized同步,代码如下:

package thread;

import java.util.concurrent.CountDownLatch;

public class ThreadAddLatch {
    public static int sum = 0;
    public static Object LOCK = new Object();
    public static CountDownLatch countdown = new CountDownLatch(4);

    public static void main(String[] args) throws InterruptedException {
        ThreadAddLatch add = new ThreadAddLatch();
        ThreadTest thread1 = add.new ThreadTest(1, 25);
        ThreadTest thread2 = add.new ThreadTest(26, 50);
        ThreadTest thread3 = add.new ThreadTest(51, 75);
        ThreadTest thread4 = add.new ThreadTest(76, 100);
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

        countdown.await();
        System.out.println("total result: "+sum);
    }

    class ThreadTest extends Thread {
        private int begin;
        private int end;

        @Override
        public void run() {
            synchronized (LOCK) {
                for (int i = begin; i <= end; i++) {
                    sum += i;
                }
                System.out.println("from "+Thread.currentThread().getName()+" sum="+sum);
            }
            countdown.countDown();
        }

        public ThreadTest(int begin, int end) {
            this.begin = begin;
            this.end = end;
        }
    }
}

输出:
from Thread-0 sum=325
from Thread-3 sum=2525
from Thread-2 sum=4100
from Thread-1 sum=5050
total result: 5050

使用cyclicbarrier

子线程执行完调用 cyclicbarrier.await(), 最后都到达barrier时,输出结果。注意:sum为共享变量,访问共享变量时,用synchronized同步,代码如下:

package thread;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class ThreadAddBarrier {
    public static int sum = 0;
    public static Object LOCK = new Object();

    public static CyclicBarrier cyclicbarrier = new CyclicBarrier(4,
            new Runnable() {
                public void run() {
                    System.out.println(sum);
                }
            });

    public static void main(String[] args) throws InterruptedException {
        ThreadAddBarrier add = new ThreadAddBarrier();
        ThreadTest thread1 = add.new ThreadTest(1, 25);
        ThreadTest thread2 = add.new ThreadTest(26, 50);
        ThreadTest thread3 = add.new ThreadTest(51, 75);
        ThreadTest thread4 = add.new ThreadTest(76, 100);
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

    }

    class ThreadTest extends Thread {
        private int begin;
        private int end;

        @Override
        public void run() {
            synchronized (LOCK) {
                for (int i = begin; i <= end; i++) {
                    sum += i;
                }
                System.out.println("from "+Thread.currentThread().getName()+" sum="+sum);
            }
            try {
                cyclicbarrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        }

        public ThreadTest(int begin, int end) {
            this.begin = begin;
            this.end = end;
        }
    }
}

输出:
from Thread-0 sum=325
from Thread-2 sum=1900
from Thread-1 sum=2850
from Thread-3 sum=5050
5050

通过线程池管理线程

用Future取得各子线程执行结果,最后将结果相加。代码如下:

package thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ThreadAddFuture {
    public static  List<Future> futureList=new ArrayList<Future>();
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        int sum=0;
        ThreadAddFuture add = new ThreadAddFuture();
        ExecutorService pool=Executors.newFixedThreadPool(4);

        for(int i=1;i<=76;){
            ThreadTest thread=add.new ThreadTest(i,i+24);
            Future<Integer> future=pool.submit(thread);
            futureList.add(future);
            i+=25;
        }

        if(futureList!=null && futureList.size()>0){
            for(Future<Integer> future:futureList){
               sum+=(Integer)future.get();
            }
        }
        System.out.println("total result: "+sum);
        pool.shutdown();
    }

    class ThreadTest implements Callable<Integer> {
        private int begin;
        private int end;
        public int sum=0;

        public ThreadTest(int begin, int end) {
            this.begin = begin;
            this.end = end;
        }

        @Override
        public Integer call() throws Exception {
            for(int i=begin;i<=end;i++){
                sum+=i;
            }
            System.out.println("from "+Thread.currentThread().getName()+" sum="+sum);
            return sum;
        }
    }
}

输出:
from pool-1-thread-3 sum=1575
from pool-1-thread-1 sum=325
from pool-1-thread-2 sum=950
from pool-1-thread-4 sum=2200
total result: 5050