Java Executor框架创建不同类型的线程池范例

Executors对象下有哪些可供我们使用的方法:

范例1:

package com.contoso;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ExecutorsExample1 {

    static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    public static void useSingleThreadExecutor() {
        
        System.out.println("=== SingleThreadExecutor ===");
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        singleThreadExecutor.execute(() -> System.out.println(Thread.currentThread().getName() + " time1 = "+ formatter.format(new Date())));
        singleThreadExecutor.execute(() -> System.out.println(Thread.currentThread().getName() + " time2 = "+ formatter.format(new Date())));
        singleThreadExecutor.shutdown();
        try {
            singleThreadExecutor.awaitTermination(4, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        useSingleThreadExecutor();
    }
}
run:
=== SingleThreadExecutor ===
pool-1-thread-1 time1 = 2019-10-24 23:11:14.307
pool-1-thread-1 time2 = 2019-10-24 23:11:14.307
BUILD SUCCESSFUL (total time: 0 seconds)

范例2:

package com.contoso;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class ExecutorsExample2 {

    static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    public static void useCachedThreadPool() {
        System.out.println("=== CachedThreadPool ===");
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        LinkedList<Future<UUID>> uuids = new LinkedList();
        for (int i = 0; i < 10; i++) {
            Future<UUID> submittedUUID = cachedThreadPool.submit(() -> {
                UUID randomUUID = UUID.randomUUID();
                System.out.println("UUID " + randomUUID + "  " + Thread.currentThread().getName()+ " time1 = "+ formatter.format(new Date()));
                return randomUUID;
            });
            uuids.add(submittedUUID);
        }
        cachedThreadPool.execute(() -> uuids.forEach((future) -> {
            try {
                System.err.println("Result " + future.get() + "  " + Thread.currentThread().getName()+ " time2 = "+ formatter.format(new Date()));
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }));
        cachedThreadPool.shutdown();
        try {
            cachedThreadPool.awaitTermination(4, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        useCachedThreadPool();
    }
}

范例3:

package com.contoso;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class ExecutorsExample3 {

    static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    public static void useFixedThreadPool() {
        System.out.println("=== FixedThreadPool ===");
        ExecutorService fixedPool = Executors.newFixedThreadPool(4);
        LinkedList<Future<UUID>> uuids = new LinkedList<Future<UUID>>();
        for (int i = 0; i < 20; i++) {
            Future<UUID> submitted = fixedPool.submit(() -> {
                UUID randomUUID = UUID.randomUUID();
                System.out.println("UUID " + randomUUID + "  " + Thread.currentThread().getName()+ " time1 = "+ formatter.format(new Date()));
                return randomUUID;
            });
            uuids.add(submitted);
        }
        fixedPool.execute(() -> uuids.forEach((future) -> {
            try {
               System.err.println("Result " + future.get() + "  " + Thread.currentThread().getName()+ " time2 = "+ formatter.format(new Date()));
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }));
        fixedPool.shutdown();
        try {
            fixedPool.awaitTermination(4, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        useFixedThreadPool();
    }
}

范例4:

package com.contoso;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ExecutorsExample4 {

    static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    public static void useScheduledThreadPool() {
        System.out.println("=== ScheduledThreadPool ===");
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4);
        scheduledThreadPool.scheduleAtFixedRate(() -> System.out.println(Thread.currentThread().getName()+ " time1 = "+ formatter.format(new Date())), 0, 2, TimeUnit.SECONDS);
        scheduledThreadPool.scheduleAtFixedRate(() -> System.out.println(Thread.currentThread().getName()+ " time2 = "+ formatter.format(new Date())), 0, 2, TimeUnit.SECONDS);
        scheduledThreadPool.scheduleWithFixedDelay(() -> System.err.println(Thread.currentThread().getName()+ " time3 = "+ formatter.format(new Date())), 0, 2, TimeUnit.SECONDS);

        try {
            scheduledThreadPool.awaitTermination(6, TimeUnit.SECONDS);
            scheduledThreadPool.shutdown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        useScheduledThreadPool();
    }
}

范例5:

package com.contoso;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ExecutorsExample5 {

    static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    public static void useSingleTreadScheduledExecutor() {
        System.out.println("=== SingleThreadScheduledThreadPool ===");
        ScheduledExecutorService singleThreadScheduler = Executors.newSingleThreadScheduledExecutor();
        singleThreadScheduler.scheduleAtFixedRate(() -> System.out.println(Thread.currentThread().getName()+ " time1 = "+ formatter.format(new Date())), 0, 2, TimeUnit.SECONDS);
        singleThreadScheduler.scheduleWithFixedDelay(() -> System.out.println(Thread.currentThread().getName()+ " time2 = "+ formatter.format(new Date())), 0, 2,TimeUnit.SECONDS);

        try {
            singleThreadScheduler.awaitTermination(6, TimeUnit.SECONDS);
            singleThreadScheduler.shutdown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        useSingleTreadScheduledExecutor();
    }
}
run:
=== SingleThreadScheduledThreadPool ===
pool-1-thread-1 time1 = 2019-10-24 23:23:16.446
pool-1-thread-1 time2 = 2019-10-24 23:23:16.447
pool-1-thread-1 time1 = 2019-10-24 23:23:18.448
pool-1-thread-1 time2 = 2019-10-24 23:23:18.448
pool-1-thread-1 time1 = 2019-10-24 23:23:20.447
pool-1-thread-1 time2 = 2019-10-24 23:23:20.449
BUILD SUCCESSFUL (total time: 6 seconds)

范例6:

package com.contoso;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
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;
import java.util.concurrent.TimeUnit;

public class ExecutorsExample6 {

    static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    public static void useWorkStealingThreadPool() {
        System.out.println("=== WorkStealingThreadPool ===");
        ExecutorService workStealingPool = Executors.newWorkStealingPool();

        workStealingPool.execute(() -> System.out.println(Thread.currentThread().getName() + " time1 = " + formatter.format(new Date())));

        Callable<UUID> generatesUUID = UUID::randomUUID;
        LinkedList<Callable<UUID>> severalUUIDsTasks = new LinkedList();
        for (int i = 0; i < 20; i++) {
            severalUUIDsTasks.add(generatesUUID);
        }

        try {
            List<Future<UUID>> futureUUIDs = workStealingPool.invokeAll(severalUUIDsTasks);
            for (Future<UUID> future : futureUUIDs) {
                if (future.isDone()) {
                    UUID uuid = future.get();
                    System.err.println(uuid + "  " + Thread.currentThread().getName() + " time2 = " + formatter.format(new Date()));
                }
            }
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        try {
            workStealingPool.awaitTermination(6, TimeUnit.SECONDS);
            workStealingPool.shutdown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        useWorkStealingThreadPool();
    }
}

范例7:如何自定义线程池和超负载时的自定义拒绝策略

package com.myth;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class RejectThreadPoolDemo {

    public static class MyTask implements Runnable {
        @Override
        public void run() {
            System.out.println(System.currentTimeMillis() + "  Thread Name:" + Thread.currentThread().getName());
            try {
                Thread.sleep(100); // 模拟任务执行需要花费100毫秒的时间,因此会导致大量的任务被直接丢弃
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        MyTask task = new MyTask();
         // 自定义一个线程池,该线程池有5个常驻线程,并且最大线程数量也是5个,相当于一个固定大小的线程池,但只定义了10个容量的等待队列,
         // 因为使用无界队列可能并不是最佳的解决方案,如果任务量很极大,很有可能会把内存撑爆,所以定义一个合理的队列大小也是合乎常理的选择
         // 其中又自定义了拒绝策略,我们不抛出异常,因为万一在任务提交端没有进行异常处理,则有可能使得整个系统都崩溃,自定义拒绝策略记
         // 录被丢弃的任务,这样设计比内置的DiscardPolicy策略更灵活一点
        ExecutorService es = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(10),
        new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                // 实际应用中,我们可以将更详细的信息记录到日志中,来分析系统的负载和任务丢失的情况
                System.out.println(r.toString() + " is discard");
            }
        });
        for (int i = 0; i < 100; i++) {
            es.submit(task);
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
run:
1572692317738  Thread Name:pool-1-thread-1
1572692317749  Thread Name:pool-1-thread-2
1572692317760  Thread Name:pool-1-thread-3
1572692317771  Thread Name:pool-1-thread-4
1572692317782  Thread Name:pool-1-thread-5
1572692317839  Thread Name:pool-1-thread-1
1572692317850  Thread Name:pool-1-thread-2
1572692317861  Thread Name:pool-1-thread-3
1572692317872  Thread Name:pool-1-thread-4
1572692317883  Thread Name:pool-1-thread-5
1572692317940  Thread Name:pool-1-thread-1
1572692317951  Thread Name:pool-1-thread-2
1572692317965  Thread Name:pool-1-thread-3
1572692317973  Thread Name:pool-1-thread-4
1572692317984  Thread Name:pool-1-thread-5
java.util.concurrent.FutureTask@3d4eac69 is discard
java.util.concurrent.FutureTask@42a57993 is discard
java.util.concurrent.FutureTask@75b84c92 is discard
java.util.concurrent.FutureTask@6bc7c054 is discard
1572692318040  Thread Name:pool-1-thread-1
1572692318051  Thread Name:pool-1-thread-2
1572692318066  Thread Name:pool-1-thread-3
1572692318074  Thread Name:pool-1-thread-4
1572692318085  Thread Name:pool-1-thread-5
java.util.concurrent.FutureTask@232204a1 is discard
java.util.concurrent.FutureTask@4aa298b7 is discard
java.util.concurrent.FutureTask@7d4991ad is discard
java.util.concurrent.FutureTask@28d93b30 is discard
1572692318140  Thread Name:pool-1-thread-1
1572692318151  Thread Name:pool-1-thread-2
1572692318166  Thread Name:pool-1-thread-3
1572692318174  Thread Name:pool-1-thread-4
1572692318185  Thread Name:pool-1-thread-5
java.util.concurrent.FutureTask@1b6d3586 is discard
java.util.concurrent.FutureTask@4554617c is discard
java.util.concurrent.FutureTask@74a14482 is discard
java.util.concurrent.FutureTask@1540e19d is discard
1572692318241  Thread Name:pool-1-thread-1
1572692318252  Thread Name:pool-1-thread-2
java.util.concurrent.FutureTask@677327b6 is discard
1572692318267  Thread Name:pool-1-thread-3
1572692318275  Thread Name:pool-1-thread-4
1572692318286  Thread Name:pool-1-thread-5
java.util.concurrent.FutureTask@14ae5a5 is discard
java.util.concurrent.FutureTask@7f31245a is discard
java.util.concurrent.FutureTask@6d6f6e28 is discard
java.util.concurrent.FutureTask@135fbaa4 is discard
1572692318342  Thread Name:pool-1-thread-1
1572692318353  Thread Name:pool-1-thread-2
1572692318368  Thread Name:pool-1-thread-3
1572692318376  Thread Name:pool-1-thread-4
1572692318387  Thread Name:pool-1-thread-5
java.util.concurrent.FutureTask@45ee12a7 is discard
java.util.concurrent.FutureTask@330bedb4 is discard
java.util.concurrent.FutureTask@2503dbd3 is discard
java.util.concurrent.FutureTask@4b67cf4d is discard
1572692318443  Thread Name:pool-1-thread-1
1572692318454  Thread Name:pool-1-thread-2
1572692318469  Thread Name:pool-1-thread-3
1572692318477  Thread Name:pool-1-thread-4
1572692318488  Thread Name:pool-1-thread-5
java.util.concurrent.FutureTask@7ea987ac is discard
java.util.concurrent.FutureTask@12a3a380 is discard
java.util.concurrent.FutureTask@29453f44 is discard
java.util.concurrent.FutureTask@5cad8086 is discard
1572692318544  Thread Name:pool-1-thread-1
1572692318555  Thread Name:pool-1-thread-2
1572692318570  Thread Name:pool-1-thread-3
1572692318578  Thread Name:pool-1-thread-4
1572692318589  Thread Name:pool-1-thread-5
java.util.concurrent.FutureTask@6e0be858 is discard
java.util.concurrent.FutureTask@61bbe9ba is discard
java.util.concurrent.FutureTask@610455d6 is discard
java.util.concurrent.FutureTask@511d50c0 is discard
1572692318652  Thread Name:pool-1-thread-1
1572692318656  Thread Name:pool-1-thread-2
1572692318671  Thread Name:pool-1-thread-3
1572692318682  Thread Name:pool-1-thread-4
1572692318690  Thread Name:pool-1-thread-5
java.util.concurrent.FutureTask@60e53b93 is discard
java.util.concurrent.FutureTask@5e2de80c is discard
java.util.concurrent.FutureTask@1d44bcfa is discard
java.util.concurrent.FutureTask@266474c2 is discard
java.util.concurrent.FutureTask@6f94fa3e is discard
1572692318753  Thread Name:pool-1-thread-1
1572692318757  Thread Name:pool-1-thread-2
1572692318772  Thread Name:pool-1-thread-3
1572692318783  Thread Name:pool-1-thread-4
1572692318791  Thread Name:pool-1-thread-5
java.util.concurrent.FutureTask@5e481248 is discard
1572692318853  Thread Name:pool-1-thread-1
1572692318858  Thread Name:pool-1-thread-2
1572692318872  Thread Name:pool-1-thread-3
1572692318883  Thread Name:pool-1-thread-4
1572692318891  Thread Name:pool-1-thread-5
1572692318954  Thread Name:pool-1-thread-1
1572692318959  Thread Name:pool-1-thread-2
1572692318973  Thread Name:pool-1-thread-3
1572692318984  Thread Name:pool-1-thread-4
1572692318992  Thread Name:pool-1-thread-5

范例8:

package com.myth;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

// 自定义扩展线程池,例如我们可以监控每个任务的开始和结束时间,在实际应用中,可以对其进行扩展来实现
// 对线程池运行状态的跟踪,输出一些有用的调试信息,以帮助对系统的故障诊断,这对于多线程程序排错很有帮助
public class CustomThreadPoolDemo {

    public static class MyTask implements Runnable {

        public String name;

        public MyTask(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            System.out.println("正在执行" + " ThreadID =" + Thread.currentThread().getId() + " ,TaskName = " + name);
            try {
                Thread.sleep(100); // 模拟任务执行需要花费100毫秒的时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        ExecutorService es = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()) {
            @Override
            protected void beforeExecute(Thread t, Runnable r) {
                System.out.println("准备执行: " + ((MyTask) r).name);
            }

            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                System.out.println("执行完成: " + ((MyTask) r).name);
            }

            @Override
            protected void terminated() {
                System.out.println("线程池退出");
            }
        };

        for (int i = 0; i < 5; i++) {
            MyTask task = new MyTask("Task" + i);
            es.execute(task);
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        es.shutdown();
    }
}
run:
准备执行: Task0
正在执行 ThreadID =10 ,TaskName = Task0
准备执行: Task1
正在执行 ThreadID =11 ,TaskName = Task1
准备执行: Task2
正在执行 ThreadID =12 ,TaskName = Task2
准备执行: Task3
正在执行 ThreadID =13 ,TaskName = Task3
准备执行: Task4
正在执行 ThreadID =14 ,TaskName = Task4
执行完成: Task0
执行完成: Task1
执行完成: Task2
执行完成: Task3
执行完成: Task4
线程池退出
BUILD SUCCESSFUL (total time: 0 seconds)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值