zoukankan      html  css  js  c++  java
  • Java实现多线程的四种实现方式

    以计算0到1000之间的和为例

    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.concurrent.*;
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class Main {
    //求1~N全部整数的和,会上溢
    int N = (int) 1e8;
    int threadSize = 5;
    
    /**
     * 最原始最基础的方式:使用thread,自定义并发
     */
    class ThreadJoin {
        void go() {
            Thread[] a = new Thread[threadSize];
            //每个线程应该干多少活
            int per = (int) Math.ceil(N * 1.0 / a.length);
            final AtomicInteger s = new AtomicInteger(0);
            for (int i = 0; i < a.length; i++) {
                int ii = i;
                a[i] = new Thread(() -> {
                    int sum = 0;
                    for (int j = ii * per; j < Math.min(ii * per + per, N); j++) {
                        sum += j;
                    }
                    s.addAndGet(sum);
                });
                a[i].start();
            }
            for (Thread i : a)
                try {
                    i.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            System.out.println(s.get() + " " + getClass().getName());
        }
    }
    
    /**
     * 重量级的多线程框架:ThreadPoolExecutor,维护一个动态线程池
     */
    class UseThreadPoolExecutor {
        void go() {
            ThreadPoolExecutor executor = new ThreadPoolExecutor(threadSize, threadSize, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
            int per = (int) (Math.ceil(1.0 * N / threadSize));
            List<Future<Integer>> futureList = new LinkedList<>();
            for (int i = 0; i < threadSize; i++) {
                final int ii = i;
                futureList.add(executor.submit(() -> {
                    int sum = 0;
                    for (int j = ii * per; j < Math.min(N, ii * per + per); j++) {
                        sum += j;
                    }
                    return sum;
                }));
            }
            int sum = 0;
            for (Future<Integer> j : futureList) {
                try {
                    sum += j.get(Integer.MAX_VALUE, TimeUnit.SECONDS);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            executor.shutdown();
            System.out.println(sum + " " + getClass().getName());
        }
    }
    
    /**
     * ExecutorService:轻量级的线程池
     */
    class UseExecutorService {
        void go() {
            ExecutorService service = Executors.newFixedThreadPool(threadSize);
            int per = (int) (Math.ceil(N * 1.0 / threadSize));
            List<Future<Integer>> futureList = new LinkedList<>();
            for (int i = 0; i < threadSize; i++) {
                final int ii = i;
                futureList.add(service.submit(() -> {
                    int sum = 0;
                    for (int j = ii * per; j < Math.min(N, ii * per + per); j++) {
                        sum += j;
                    }
                    return sum;
                }));
            }
            int sum = 0;
            for (Future<Integer> j : futureList) {
                try {
                    sum += j.get(Integer.MAX_VALUE, TimeUnit.SECONDS);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            service.shutdown();
            System.out.println(sum + " " + getClass().getName());
        }
    }
    
    /**
     * 模拟Linux fork join操作
     */
    
    class UseForkJoin {
        void go() {
            int per = (int) (Math.ceil(1.0 * N / threadSize));
            List<ForkJoinTask<Integer>> a = new ArrayList<>(threadSize);
            for (int i = 0; i < threadSize; i++) {
                final int ii = i;
                a.add(new RecursiveTask<Integer>() {
                    @Override
                    protected Integer compute() {
                        int sum = 0;
                        for (int j = ii * per; j < Math.min(N, ii * per + per); j++) {
                            sum += j;
                        }
                        return sum;
                    }
                });
                a.get(i).invoke();
            }
            int s = 0;
            for (ForkJoinTask<Integer> i : a) {
                s += i.join();
            }
            System.out.println(s + " " + getClass().getName());
        }
    }
    
    Main() {
        new ThreadJoin().go();
        new UseExecutorService().go();
        new UseThreadPoolExecutor().go();
        new UseForkJoin().go();
    }
    
    public static void main(String[] args) {
        new Main();
    }
    }
    
    
  • 相关阅读:
    [LeetCode] Bulb Switcher II 灯泡开关之二
    [LeetCode] Second Minimum Node In a Binary Tree 二叉树中第二小的结点
    [LeetCode] 670. Maximum Swap 最大置换
    [LeetCode] Trim a Binary Search Tree 修剪一棵二叉搜索树
    [LeetCode] Beautiful Arrangement II 优美排列之二
    [LeetCode] Path Sum IV 二叉树的路径和之四
    [LeetCode] Non-decreasing Array 非递减数列
    [LeetCode] 663. Equal Tree Partition 划分等价树
    [LeetCode] 662. Maximum Width of Binary Tree 二叉树的最大宽度
    [LeetCode] Image Smoother 图片平滑器
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/9703790.html
Copyright © 2011-2022 走看看