前言:复习总结一下java实现线程的三种方式与JUC中现成的4种线程池
实现线程的三种简单方式 继承java.lang.Thread类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class MyThread extends Thread { public void run () { System.out.println(getName() + "的run()方法在运行" ); } } public class Main { public static void main (String[] args) { final int N = 10 ; MyThread[] myThread = new MyThread[N]; for (int i = 0 ; i < N; i++) { myThread[i] = new MyThread(); } for (int i = 0 ; i < N; i++) { myThread[i].start(); } } }
实现java.lang.Runnable接口 java只支持单继承,所以继承java.lang.Thread类有局限性,因此实现java.lang.Runnable接口是一个更好的选择
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class MyThread implements Runnable { public void run () { System.out.println(Thread.currentThread().getName() + "的run()方法在运行" ); } } public class Main { public static void main (String[] args) { final int N = 10 ; Thread[] threads = new Thread[N]; for (int i = 0 ; i < N; i++) { threads[i] = new Thread(new MyThread()); } for (int i = 0 ; i < N; i++) { threads[i].start(); } } }
也可以创建一个 实现Runnable接口类的实例,赋值给多个Thread
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class MyThread implements Runnable { private int num = 0 ; @Override public void run () { for (int i = 0 ; i < 1000 ; i++) { num++; } System.out.println(Thread.currentThread().getName() + " " + num); } public static void main (String[] args) { MyThread myThread = new MyThread(); for (int i = 0 ; i < 10 ; i++) { new Thread(myThread).start(); } } }
运行结果:
通过Callable和FutureTask创建线程 Java 5.0 在 java.util.concurrent 提供了一个新的创建执行线程的方式: 实现 Callable 接口。
Callable 接口类似于 Runnable,但是 Runnable 不会返回结果,并且无法抛出经过检查的异常,而 Callable 依赖 FutureTask 类获取返回结果。
Callable类图
FutureTask类图
代码
1 2 3 4 5 6 7 8 9 10 11 public class MyThread implements Callable <String > { public void run () { System.out.println("线程 " + this .toString() + "执行结束" ); } @Override public String call () throws Exception { return null ; } }
1 2 3 4 5 6 7 8 9 10 11 12 public class Main { public static void main (String[] args) { try { FutureTask<String> futureTask = new FutureTask<String>(new MyThread()); new Thread(futureTask).start(); } catch (Exception e) { e.printStackTrace(); } } }
通过线程池创建线程 java.util.concurrent包中已经提供为大多数使用场景的内置线程池
Executors.newSingleThreadExecutor() 单条线程
Executors.newFixedThreadPool(int n) 固定数目线程的线程池
Executors.newCachedThreadPool() 创建一个可缓存的线程池,调用execute将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有60秒钟未被使用的线程。
Executors.newScheduledThreadPool(int n) 支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
类图
Executors.newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
newSingleThreadExecutor 方法源码
核心线程数1,线程池最大数量1,线程空闲存活时间为0,时间单位毫秒,阻塞队列为LinkedBlockingQueue,允许请求队列长度为Integer.MAX_VALUE,可能会堆积大量请求,导致OOM,第二个方法允许自定义ThreadFactory线程工厂
1 2 3 4 5 6 public static ExecutorService newSingleThreadExecutor () { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1 , 1 , 0L , TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
newSingleThreadExecutor实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class Main { public static void main (String[] args) { ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(new Runnable() { @Override public void run () { System.out.println(Thread.currentThread().getName()); } }); executorService.shutdown(); } }
Executors.newFixedThreadPool newFixedThreadPool方法源码
核心线程数n,线程池最大数量n,线程空闲存活时间为0,时间单位毫秒,阻塞队列为LinkedBlockingQueue,允许请求队列长度为Integer.MAX_VALUE,可能会堆积大量请求,导致OOM,第二个方法允许自定义ThreadFactory线程工厂
1 2 3 4 5 6 7 8 9 10 11 12 public static ExecutorService newFixedThreadPool (int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L , TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } public static ExecutorService newFixedThreadPool (int nThreads, ThreadFactory threadFactory) { return new ThreadPoolExecutor(nThreads, nThreads, 0L , TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory); }
newFixedThreadPool实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Main { public static void main (String[] args) { final int THREADNUM = 5 ; ExecutorService executorService = Executors.newFixedThreadPool(THREADNUM); for (int i = 0 ; i < THREADNUM; i++) { executorService.execute(new Runnable() { @Override public void run () { System.out.println(Thread.currentThread().getName()); } }); } executorService.shutdown(); } }
Executors.newCachedThreadPool newCachedThreadPool方法源码
核心线程数0,线程池最大数量Integer.MAX_VALUE,允许创建线程为Integer.MAX_VALUE,可能会创建大量线程,导致OOM,线程空闲存活时间为60,时间单位秒,阻塞队列为SynchronousQueue,,第二个方法允许自定义ThreadFactory线程工厂
1 2 3 4 5 6 7 8 9 10 11 12 public static ExecutorService newCachedThreadPool () { return new ThreadPoolExecutor(0 , Integer.MAX_VALUE, 60L , TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } public static ExecutorService newCachedThreadPool (ThreadFactory threadFactory) { return new ThreadPoolExecutor(0 , Integer.MAX_VALUE, 60L , TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), threadFactory); }
newCachedThreadPool实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Main { public static void main (String[] args) { final int THREADNUM = 5 ; ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0 ; i < THREADNUM; i++) { executorService.execute(new Runnable() { @Override public void run () { System.out.println(Thread.currentThread().getName()); } }); } executorService.shutdown(); } }
Executors.newScheduledThreadPool newScheduledThreadPool方法源码
核心线程数为N,线程池最大数量Integer.MAX_VALUE,允许创建线程为Integer.MAX_VALUE,可能会创建大量线程,导致OOM,线程空闲存活时间为0,时间单位毫秒,阻塞队列为BlockingQueue,允许自定义ThreadFactory线程工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public static ScheduledExecutorService newScheduledThreadPool (int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } public ScheduledThreadPoolExecutor (int corePoolSize) { super (corePoolSize, Integer.MAX_VALUE, 0 , NANOSECONDS, new DelayedWorkQueue()); } public ThreadPoolExecutor (int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this (corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
newScheduledThreadPool实例 定时执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Main { public static void main (String[] args) { final int THREADNUM = 5 ; ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(THREADNUM); for (int i = 0 ; i < THREADNUM; i++) { scheduledThreadPool.schedule(new Runnable() { @Override public void run () { System.out.println(Thread.currentThread().getName()); } }, 1 , TimeUnit.SECONDS); } scheduledThreadPool.shutdown(); } }