线程池

线程池使用及优势

线程池做的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量超出数量的线程排队等候,等其他线程执行完毕,再从队列中取出任务来执行。

主要特点

线程复用;控制最大并发数;管理线程。

  • 第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
  • 第二,提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
  • 第三,提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

线程池如何使用?

架构说明

Java中的线程池是通过Executor框架实现的,该框架中用到了Executor,Executors,ExecutorService,ThreadPoolExecutor这几个类。
线程池的底层就是ThreadPoolExecutor
线程池

线程池3个常用方式

newFixedThreadPool

package com.threadTest;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 线程池
 * 第四种获得/使用java多线程的方式,  前三种分别是 继承Thread类,实现Runnable接口,实现callable接口(有返回值有异常)
 *
 */
public class MyThreadPoolDemo {
	public static void main(String[] args) {
		//一池5个处理线程
		ExecutorService threadPool = Executors.newFixedThreadPool(5);
		
		//模拟10个用户来办理业务,每个用户就是一个来自外部的请求线程
		try {
			for (int i = 1; i <= 10; i++) {
				threadPool.execute(() -> {
					System.out.println(Thread.currentThread().getName()+"\t 办理业务");
				});
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			threadPool.shutdown();
		}
		
	}
}

线程池

newSingleThreadExecutor

package com.threadTest;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 线程池
 * 第四种获得/使用java多线程的方式,  前三种分别是 继承Thread类,实现Runnable接口,实现callable接口(有返回值有异常)
 *
 */
public class MyThreadPoolDemo {
	public static void main(String[] args) {
		//一池1个处理线程
		ExecutorService threadPool = Executors.newSingleThreadExecutor();
		
		//模拟10个用户来办理业务,每个用户就是一个来自外部的请求线程
		try {
			for (int i = 1; i <= 10; i++) {
				threadPool.execute(() -> {
					System.out.println(Thread.currentThread().getName()+"\t 办理业务");
				});
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			threadPool.shutdown();
		}
		
	}
}

线程池

newCachedThreadPool

package com.threadTest;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 线程池
 * 第四种获得/使用java多线程的方式,  前三种分别是 继承Thread类,实现Runnable接口,实现callable接口(有返回值有异常)
 *
 */
public class MyThreadPoolDemo {
	public static void main(String[] args) {
		//一池N个处理线程
		ExecutorService threadPool = Executors.newCachedThreadPool();
		
		//模拟10个用户来办理业务,每个用户就是一个来自外部的请求线程
		try {
			for (int i = 1; i <= 10; i++) {
				threadPool.execute(() -> {
					System.out.println(Thread.currentThread().getName()+"\t 办理业务");
				});
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			threadPool.shutdown();
		}
		
	}
}

线程池
但是如果每次停0.2秒呢?

package com.threadTest;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 线程池
 * 第四种获得/使用java多线程的方式,  前三种分别是 继承Thread类,实现Runnable接口,实现callable接口(有返回值有异常)
 *
 */
public class MyThreadPoolDemo {
	public static void main(String[] args) {
		//一池N个处理线程
		ExecutorService threadPool = Executors.newCachedThreadPool();
		
		//模拟10个用户来办理业务,每个用户就是一个来自外部的请求线程
		try {
			for (int i = 1; i <= 10; i++) {
				threadPool.execute(() -> {
					System.out.println(Thread.currentThread().getName()+"\t 办理业务");
				});
				//暂停200毫秒
				try {TimeUnit.MILLISECONDS.sleep(200);}catch(InterruptedException e) {e.printStackTrace();}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			threadPool.shutdown();
		}
		
	}
}

说明应付得过来就不需要那么多线程,这个机制是灵活处理。
线程池

底层是什么?

底层都是ThreadPoolExecutor

newFixedThreadPool

  • 1.创建一个定长线程池,可以控制线程最大并发数,超出的线程会在队列中等待
  • 2.newFixedThreadPool创建的线程池corePoolSize和maximumPoolSize值时相等的,它使用的LinkedBlockingQueue;
 public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

线程池

newSingleThreadExecutor

  • 1.创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。
  • 2.newSingleThreadExecutor将corePoolSize和maximumPoolSize都设置为1,它使用的LinkedBlockingQueue;
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

线程池

newCachedThreadPool

  • 1.创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
  • 2.newCachedThreadPool将corePoolSize设置为0,将maximumPoolSize设置为Integer.MAX_VALUE,使用的SynchronousQueue,也就是说来了任务就创建线程运行,当线程空闲超过60秒,就销毁线程。

线程池

线程池线程池 等我下课 发布了24 篇原创文章 · 获赞 21 · 访问量 6104 私信 关注
上一篇:Java 并发之 Executor 框架


下一篇:JAVA面试题——对线程池的理解