newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
Runable类:
public class RunThread implements Runnable {
private int count = 0;
@Override
public void run() {
boolean flag = true;
while (flag) {
System.out.println("hello!");
count++;
if (count == 3) {
flag = false;
}
}
}
}
测试类:
public class Test {
public static void main(String[] args) {
RunThread runThread = new RunThread();
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(runThread);
Future<List<String>> future = executor.submit(new ListCallable());
try {
List<String> list = future.get(60L, TimeUnit.MINUTES);
System.out.println("the result==" + list.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
private static class ListCallable implements Callable<List<String>> {
@Override
public List<String> call() throws Exception {
List<String> list = Arrays.asList("zhangsan", "lisi", "wangwu");
return list;
}
}
}
输出结果:
hello!
hello!
hello!
the result==[zhangsan, lisi, wangwu]
submit()和execute()的区别:
public interface Executor {
void execute(Runnable command);
}
execute()方法的入参为一个Runnable,返回值为void
public interface ExecutorService extends Executor {
...
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
...
}
在ExecutorService接口中,一共有以上三个sumbit()方法,入参可以为Callable<T>,也可以为Runnable,而且方法有返回值Future<T>;
1、submit()有返回值,而execute()没有。
2、如果task里会抛出checked或者unchecked exception,而你又希望外面的调用者能够感知这些exception并做出及时的处理,那么就需要用到submit,通过对Future.get()进行抛出异常的捕获,然后对其进行处理。
Executors创建线程的其他方式:
- newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
- newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
- newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。