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)