线程池与异步编排

线程创建方法

/**
 * 〈简述〉<br>
 * 〈多线程测试类〉
 *
 * @create 2020/6/18
 * @since 1.0.0
 */
public class MultithreadingTest {
    private static int i = 0;

    public static void main(String args[]) {
        printThreadName();
        /*方法一*/
        Thread t1 = new ThreadTest();
        t1.start();
        /*方法二*/
        Thread t2 = new Thread(new RunnableTest());
        t2.start();
        /*方法三*/
        FutureTask futureTask = new FutureTask(new CallableTest());
        Thread t3 = new Thread(futureTask);
        t3.start();
        Object obj = null;
        try {
            obj = futureTask.get();//阻塞线程的方法,等待异步结果的返回
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        print("异步返回结果:" + obj);
    }

    private static class CallableTest implements Callable {

        /**
         * 配合RunnableFuture接口实现异步结果的返回
         */
        @Override
        public Object call() throws Exception {
            printThreadName();
            doSomeThing();
            return getThreadName() + " -->" + i;
        }
    }

    private static class RunnableTest implements Runnable {

        /**
         * 自定义Runnable接口编写异步任务
         *
         * @see Thread#run()
         */
        @Override
        public void run() {
            printThreadName();
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            doSomeThing();
        }
    }

    private static class ThreadTest extends Thread {
        /**
         * 自定义Thread子类实现run方法
         *
         * @see #start()
         * @see #stop()
         * @see #Thread(ThreadGroup, Runnable, String)
         */
        @Override
        public void run() {
            printThreadName();
            doSomeThing();
        }
    }

    private static Integer doSomeThing() {
        print(getThreadName() + "(" + i + ") start");
        synchronized (MultithreadingTest.class) {
            i += 1;
        }
        print(getThreadName() + "(" + i + ") end");
        return i;
    }

    private static void printThreadName() {
        print(getThreadName());
    }

    private static String getThreadName() {
        return Thread.currentThread().getName();
    }

    private static void print(String msg) {
        System.out.println(msg);
    }
}

线程池

/**
 * 〈简述〉<br>
 * 〈测试线程池的类〉
 *
 * @create 2020/11/17
 * @since 1.0.0
 */
public class ThreadPoolTest {
    /*java线程池配置参数解析*/
    private static ThreadPoolExecutor executor = new ThreadPoolExecutor(
            10,//核心线程数(不会回收)
            20,//最大线程数
            10,//空闲线程存活时间,(20-10=10)个线程的空闲存活时间
            TimeUnit.SECONDS,//存活时间单位
            new LinkedBlockingDeque(30),//任务队列
            /*当该线程池接收到100个任务时,
            其中10任务直接执行(核心线程数10)。
            30个任务进入任务队列等待(任务队列大小30)。
            然后线程池再开启10个线程处理任务(最大线程数20)。
            剩余的50个线程会执行拒绝策略。
            ThreadPoolExecutor.CallerRunsPolicy——将新任务转为同步执行
            ThreadPoolExecutor.AbortPolicy——抛弃新任务并抛出错误
            ThreadPoolExecutor.DiscardOldestPolicy——抛弃队列中最长时间没有被执行的任务,队列第一个
            ThreadPoolExecutor.DiscardPolicy——抛弃新任务
            */
            new ThreadPoolExecutor.DiscardPolicy()
    );
    /*核心线程数为0的线程池,所有线程都可以被回收*/
    private static ExecutorService cached = Executors.newCachedThreadPool();
    /*固定大小的线程池,核心线程数=最大线程数,所有线程都不会被回收*/
    private static ExecutorService fixed = Executors.newFixedThreadPool(10);
    /*定时执行的线程池,处理定时任务*/
    private static ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(5);
    /*单线程的线程池,核心线程数=最大线程数=1*/
    private static ExecutorService single = Executors.newSingleThreadExecutor();

    public static void main(String[] args) {
        executor.execute(() -> {
            String msg = "这是一个异步任务!";
            print(msg);
        });

        Map<String, String> result = new HashMap<>();
        Future<Map<String, String>> submit = executor.submit(new MyRunnable(result), result);
        print("submit=" + getFutureGet(submit));

        cached.execute(() -> {
            print("cached");
            Future<Integer> cached2 = cached.submit(() -> {
                print("cached2");
                return 10101;
            });
            print("cached2=" + getFutureGet(cached2));
        });

        Future<Integer> fixed = ThreadPoolTest.fixed.submit(() -> {
            print("fixed");
            return 222;
        });
        print("fixed=" + getFutureGet(fixed));

        scheduled.schedule(() -> {
            print("延迟执行!");
        }, 3L, TimeUnit.SECONDS);

        Future<Integer> single = ThreadPoolTest.single.submit(() -> {
            print("single");
            return 11111;
        });
        print("single=" + getFutureGet(single));
    }

    private static <T> T getFutureGet(Future<T> submit) {
        try {
            return submit.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static void print(String msg) {
        System.out.println(Thread.currentThread().getName() + " " + msg);
    }

    public static class MyRunnable implements Runnable {
        private Map<String, String> map;

        public MyRunnable(Map<String, String> result) {
            this.setMap(result);
        }

        @Override
        public void run() {
            print("哈哈!");
            map.put("MyRunnable", "异步执行了:" + Thread.currentThread().getName());
        }

        public Map<String, String> getMap() {
            return map;
        }

        public void setMap(Map<String, String> map) {
            this.map = map;
        }
    }
}

Spring线程池配置

<bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="10"/>
    <property name="maxPoolSize" value="50"/>
    <property name="queueCapacity" value="10000"/>
    <property name="keepAliveSeconds" value="300"/>
    <property name="rejectedExecutionHandler">
        <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"/>
    </property>
</bean>

CAS原理

/**
 * 〈简述〉<br>
 * 〈测试CAS原理的类〉
 *
 * @create 2020/7/6
 * @since 1.0.0
 */
public class TestCASRule {
    static int n;
    static AtomicInteger atomicInteger;

    public static void main(String args[]) throws InterruptedException {
        int j = 0;
        while (j < 100) {
            n = 0;
            atomicInteger = new AtomicInteger(0);//创建原子整数
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    calculate();
                }
            }, "线程一");
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    calculate();
                }
            }, "线程二");
            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            endPrint();

            j++;
        }
    }

    private static void endPrint() {
        //            System.out.println("n的最终值是:" + n);
        System.out.println("atomicInteger的最终值是:" + atomicInteger.get());
    }

    private static void calculate() {
        for (int i = 0; i < 1000; i++) {
//            n++;
            atomicInteger.getAndIncrement();//对应n++
//            threadPrint();
        }
    }

    private static void threadPrint() {
        System.out.println(Thread.currentThread().getName() + "执行中。。。。。。");
    }

}

CompletableFuture异步编排

/**
 * 〈简述〉<br>
 * 〈测试异步编排的类〉
 *
 * @create 2020/11/17
 * @since 1.0.0
 */
public class CompletableFutureTest {

    private static ThreadPoolExecutor executor = new ThreadPoolExecutor(
            10,//核心线程数(不会回收)
            20,//最大线程数
            10,//空闲线程存活时间,(20-10)个线程的空闲存活时间
            TimeUnit.SECONDS,//存活时间单位
            new LinkedBlockingDeque(30),//任务队列
            /*当该线程池接收到100个任务时,
            其中10任务直接执行(核心线程数10)。
            30个任务进入任务队列等待(任务队列大小30)。
            然后线程池再开启10个线程处理任务(最大线程数20)。
            剩余的50个线程会执行拒绝策略。
            ThreadPoolExecutor.CallerRunsPolicy——将新任务转为同步执行
            ThreadPoolExecutor.AbortPolicy——抛弃新任务并抛出错误
            ThreadPoolExecutor.DiscardOldestPolicy——抛弃队列中最长时间没有被执行的任务,队列第一个
            ThreadPoolExecutor.DiscardPolicy——抛弃新任务
            */
            new ThreadPoolExecutor.DiscardPolicy()
    );

    private static Integer m = 0;

    public static void main(String[] args) {
        /*异步执行一个无返回值的任务后,再执行一个任务*/
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            print("无返回值的异步任务开始了!要睡3秒。");
            sleep(3000);
            print("睡醒了!");
        }, executor).whenComplete((t, u) -> {
            print("结果:" + t, "异常:" + u);
            bug("完成后抛出的错误!");
        }).exceptionally(e -> {
            print("异常=" + e);
            return null;
        });

        /*有返回值的异步任务*/
        CompletableFuture<Serializable> handle = CompletableFuture.supplyAsync(() -> {
            print("有返回值的异步开始了!");
            calculate();
            print("已经计算了:" + m);
//            bug();
            return m;
        }, executor).handle((t, u) -> {
            if (null == u) {
                print("接收到的入参:" + t);
                return ++t;
            } else {
                print("是不是异常了?" + u);
                return u;
            }
        }).thenApplyAsync((t) -> {
            print("下一步异步操作的入参:", t);
            if (t instanceof Integer) {
                return (Integer) t + 1;
            } else {
                return t;
            }
        }, executor);

        /*异步执行一个有返回值的任务,并利用返回值执行后续任务*/
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            print("异步处理有返回值的异步任务开始了!");
            calculate();
            return m;
        }, executor).handleAsync((t, u) -> {
            print("又一个线程接收到结果了:" + t, u);
            return m + t;
        }, executor).handleAsync((e, u) -> {
            print("处理结果:" + e, u);
            return e + 1;
        }, executor);

        future1.runAfterBoth(future, () -> {
            print("等待其他两个线程完成后执行");
        });

        future1.runAfterEitherAsync(future, () -> {
            print("等待任意一个线程完成后执行");
        });

        CompletableFuture<String> future2 = future1.thenCombineAsync(handle, (u, v) -> {
            print("两个任务之后处理的入参", u, v);
            return u + "-" + v;
        }, executor);

        future2.thenAcceptBothAsync(future1, (t, u) -> {
            print("接受两个任务的结果,调用无返回值的方法", t, u);
        }, executor);

        /*任意一个异步返回后执行*/
        CompletableFuture<Object> anyOf = CompletableFuture.anyOf(future, handle, future1);

        /*等待全部任务执行完成后执行*/
        CompletableFuture<Void> allOf = CompletableFuture.allOf(future, handle, future1);

        print("任意线程返回值: " + getFutureGet(anyOf));
        print("最终handle结果:" + getFutureGet(handle));
        print("异步处理的结果:" + getFutureGet(future1));
        print("两个任务之后处理的结果:" + getFutureGet(future2));
        getFutureGet(allOf);
        print("全部线程返回的结果集合:" + getFutureGet(future),
                getFutureGet(handle),
                getFutureGet(future1),
                getFutureGet(future2)
        );
    }

    private static <T> T getFutureGet(CompletableFuture<T> handle) {
        try {
            return handle.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static void bug() {
        String message = "故意抛出的错误!";
        bug(message);
    }

    private static void bug(String message) {
        if (true) {
            throw new RuntimeException(message);
        }
    }

    private static void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            print("睡觉出错了:" + e.getMessage());
        }
    }

    private static void calculate() {
        m++;
    }

    private static void print(Object... messages) {
        StringBuffer msg = new StringBuffer();
        for (int i = 0; i < messages.length; i++) {
            msg.append(messages[i]);
            if (i < messages.length - 1) {
                msg.append(",");
            }
        }
        System.out.println(Thread.currentThread().getName() + " " + msg);
    }

}
posted @ 2020-11-17 16:25  howard4  阅读(216)  评论(0)    收藏  举报