JAVA高级基础(70)---并发编程Executor简介及线程池的创建方式

版权声明:如需转载请标明出处 https://blog.csdn.net/yj201711/article/details/85263018

并发编程--Executor

我们在传统多线程编程创建线程时常常是创建一些 Runnable 对象,然后创建对应的Thread对象执行它们,但是如果程序需要并发执行大量的任务时,需要为每个任务都创建一个Thread,进行管理,这将会影响程序的执行效率,并且创建线程过多将会使系统负载过重。

在Java 5 之后,并发编程引入看一堆新的启动、调度和管理线程的API。Executor框架便是Java 5 中引入的,其内部使用了线程池机制,它在java.util.cocurrent 包下,通过该框架来控制线程的启动、执行和关闭,可以简化并发编程的操作。因此,在Java 5 之后,通过Executor来启动线程比使用Thread的start方法更好,除了更易管理,效率更好(用线程池实现,节约开销)外。

为什么引入Executor线程池框架

new Thread()的缺点

  1. 每次new Thread()耗费性能
  2. 调用new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制创建,之间相互竞争,会导致过多占用系统资源导致系统瘫痪。
  3. 不利于扩展,比如如定时执行、定期执行、线程中断

采用线程池的优点

  1. 重用存在的线程,减少对象创建、消亡的开销,性能佳
  2. 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞
  3. 提供定时执行、定期执行、单线程、并发数控制等功能

Executor框架

Executor框架集对线程调度进行了封装,将任务提交和任务执行解耦。它提供了线程生命周期调度的所有方法,打打简化 线程调度和同步的门槛。

Executors

创建线程池:ThreadPool

            用到的工具类:Executors

第一种方式


    线程池执行任务:void execute(Runnable command)
    在执行任务时,会使用线程池中不确定的线程去执行当前任务。线程如果处于空闲状态,就有可能会执行当前任务

第二种方式
    
        创建带有缓存的线程池 会创建一定的线程。
        在使用线程池去执行任务时,如果当前线程池中由可用线程,则直接执行任务
        如果当前线程池中的所有线程都处于非空闲状态,则会创建新的线程。

第三种方式


         单线程的线程池,在该线程池中,只有一个线程存在。

第四种方式


    线程池中的线程创建在执行任务时,可以定时执行,用到schedule(Runnable command, long delay, TimeUnit unit)
        command   需要执行的任务时Runnable的实现类
        delay          延迟的时间的数
        unit             延迟的时间的单位

这四种方式都是用的Executors中的ThreadFactory简历的线程,下面就以上四个方法做个比较

package org.lanqiao.executor.demo;

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

public class ThreadPoolDemo {
	public static void main(String[] args) {
		//ExecutorService es = Executors.newFixedThreadPool(5);
		//ExecutorService es = Executors.newCachedThreadPool();
		//ExecutorService es = Executors.newSingleThreadExecutor();
		ScheduledExecutorService ses =  Executors.newScheduledThreadPool(5);
		for(int i = 0 ; i < 20 ; i++) {
			Runnable run  = new Runnable() {
				
				@Override
				public void run() {
					System.out.println(Thread.currentThread().getName());
					
					
				}
			};
			ses.schedule(run, 5000, TimeUnit.MILLISECONDS);
		}
		
		

		
		
		
		
	}
}

猜你喜欢

转载自blog.csdn.net/yj201711/article/details/85263018