多线程实现加法(三种创建线程的方式)

    技术2025-11-17  19

    文章目录

    三种创建线程的方法继承Thread类(没有返回值)实现Runable接口(没有返回值)实现Callable接口(有返回值) CountDownLatch

    三种创建线程的方法

    利用多线程去计算加法,主要有三步

    分解任务为子任务新建线程执行子任务(如何得到结果或保存结果)得到子任务的结果,合并得到最终结果

    创建线程主要有三种方法,前两种没有返回值,callable接口有返回值。

    继承Thread类(没有返回值)

    //继承thread类,需要重写run方法 public class SumThread extends Thread { private long start; private long end; private int num; private long[] result; //这个是为了判断所有线程是否全部执行完,因为继承thread类的线程没有返回值 private CountDownLatch cdl; public SumThread(long start, long end, int num, long[] result, CountDownLatch cdl) { this.start = start; this.end = end; this.num = num; this.result = result; this.cdl = cdl; } //需要重写run方法 @Override public void run() { long sum = 0; for (long i=start;i<end;i++){ sum += i; } result[num] = sum; //计数器减一 cdl.countDown(); } } public class SumParallelThread { public static void main(String[] args) throws InterruptedException{ int N = 90000000; int numThread = 3; parallel(N, numThread); } public static void parallel(int N, int numThread) throws InterruptedException{ //通过一个数组来记录各个子线程的计算结果 long[] result = new long[numThread]; //CountDownLatch可以看作计数器 CountDownLatch cdl = new CountDownLatch(numThread); long start = System.currentTimeMillis(); for (int i=0;i<numThread;i++){ //新建线程,start方法启动线程 SumThread thread = new SumThread(i*N/numThread, (i+1)*N/numThread, i, result, cdl); thread.start(); } //等待所有线程执行完毕,在进行最后的加法 cdl.await(); long sum = 0; for (long r : result) sum += r; long end = System.currentTimeMillis(); System.out.println("并行计算结果:"+sum); System.out.println("并行计算时间:"+(end-start)+"ms"); } }

    实现Runable接口(没有返回值)

    public class SumThreadRunnable implements Runnable { private long start; private long end; private long[] result; private CountDownLatch cdl; private int num; public SumThreadRunnable(long start, long end, long[] result, CountDownLatch cdl, int num){ this.start = start; this.end = end; this.result = result; this.cdl = cdl; this.num = num; } //重写run方法 @Override public void run() { long sum = 0; for (long i=start;i<=end;i++){ sum += i; } result[num] = sum; cdl.countDown(); } } public class SumParallelRunnable { public static void main(String[] args) throws InterruptedException{ int N = 90000000; int numThread = 3; countDownLatchSum(N, numThread); } public static void countDownLatchSum(int N, int numThread) throws InterruptedException{ long start = System.currentTimeMillis(); //这个对象也是为了判断所有子线程是否全部执行完成 CountDownLatch cdl = new CountDownLatch(numThread); //和上一个一样,使用一个数组来保存子线程的计算结果 long[] result = new long[numThread]; long sum = 0; for (int i=0;i<numThread;i++){ //runable作为target去新建线程,调用start方法执行子线程 new Thread(new SumThreadRunnable(i*N/numThread, (i+1)*N/numThread, result, cdl, i)).start(); } cdl.await(); for (long r : result) sum += r; long end = System.currentTimeMillis(); System.out.println("并行计算耗时:"+(end-start)+"ms"); System.out.println("并行计算结果:"+sum); } }

    实现Callable接口(有返回值)

    public class SumThreadCallable implements Callable<Long> { private long start; private long end; public SumThreadCallable(long start, long end){ this.start = start; this.end = end; } //重写call方法,会有返回值 @Override public Long call() throws Exception { long sum = 0; for (long i=start;i<end;i++){ sum += i; } return sum; } } public class SumParallelCallable { public static void main(String[] args) throws ExecutionException, InterruptedException { int numThread = 3; int N = 90000000; parallel(N, numThread); } public static void parallel(int N, int numThread) throws ExecutionException, InterruptedException{ //新建线程池 ExecutorService executor = Executors.newFixedThreadPool(numThread); long start1 = System.currentTimeMillis(); //使用Future记录返回值 List<Future<Long>> ans = new ArrayList<>(); for (int i=0;i<numThread;i++){ //使用submit向线程池提交线程,会有返回值 //使用execute提交的线程,没有返回值 Future<Long> a = executor.submit(new SumThreadCallable(i*N/numThread, (i+1)*N/numThread)); ans.add(a); } long sum = 0; for (Future<Long> i : ans){ long tmp = i.get(); System.out.println("线程"+i+"的结果是:"+tmp); sum += tmp; } long end1 = System.currentTimeMillis(); System.out.println("并行计算耗时:"+(end1-start1)+"ms"); System.out.println("并行计算结果:"+sum); } }

    CountDownLatch

    countDownLatch 像是一个计数器,线程完成一个记录一个,计数器递减,只能使用一次。 可以用来控制线程按顺序执行,主要有以下几个方法:

    //构造方法,count是计数器的初值 public CountDownLatch(int count) {}; //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行 public void await() throws InterruptedException { }; //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行 public boolean await(long timeout, TimeUnit unit) throws InterruptedException { }; //将count值减1 public void countDown() {};
    Processed: 0.033, SQL: 9