栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

线程池Executors

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

线程池Executors

目录

为什么要用线程池

线程池的好处

Java中的四种线程池

1.缓存线程池

 2.定长线程池

3.单线程池

 4. 周期性任务定长线程池


为什么要用线程池

如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程 就会大大降低 系统的效率,因为频繁创建线程和销毁线程需要时间. 线程池就是一个容纳多个线程的容 器,池中的线程可以反复使用,省去了频繁创建线程对象的操作,节省了大量的时间和资源。

线程池的好处
  • 降低资源消耗。
  • 提高响应速度。
  • 提高线程的可管理性。

Java中的四种线程池

1.缓存线程池

 缓存线程池:长度无限制

 执行流程: 1. 判断线程池是否存在空闲线程

                  2. 存在则使用

                  3. 不存在,则创建线程 并放入线程池, 然后使用 

package huabcun;

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

public class Demo_2 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		//创建一个线程池
		ExecutorService s = Executors.newCachedThreadPool();
		//向线程池中加入新的任务1
		s.execute(new Runnable(){
			public void run() {
				System.out.println(Thread.currentThread().getName()+"好饿");
			}
		});
		//向线程池中加入新的任务2
		s.execute(new Runnable(){
			public void run() {
				System.out.println(Thread.currentThread().getName()+"好饿好饿");
			}
		});
		//向线程池中加入新的任务3
		s.execute(new Runnable(){
			public void run() {
				System.out.println(Thread.currentThread().getName()+"好饿好饿好饿");
			}
		});
	try {
		Thread.sleep(1000);
	} catch (InterruptedException e) {
		// TODO 自动生成的 catch 块
		e.printStackTrace();
	}
	//向线程池中加入新的任务4
	s.execute(new Runnable(){
		public void run() {
			System.out.println(Thread.currentThread().getName()+"真的好饿好饿好饿");
		}
	});

	}

}

 

 结果:发现4个任务三个都是使用的线程2,说明线程池为无限大,当执行第二个任务时第一个任务已经还未完成,执行第三个和第四个,第二个任务已经完成,会复用执行第二个任务的线程,而不用每次新建线程。

 2.定长线程池

定长线程池:长度是指定的数值。

 执行流程: 1. 判断线程池是否存在空闲线程

                  2. 存在则使用 

                  3. 不存在空闲线程,且线程池未满的情况下,则创建线程 并放入线程池, 然后使用

                  4. 不存在空闲线程,且线程池已满的情况下,则等待线程池存在空闲线程 

package dingchang;

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

public class Demo_1 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		//创建线程池长度为2
		ExecutorService s = Executors.newFixedThreadPool(2);
		//线程池任务1,延迟时间可不加为了看起来好理解才加
		s.execute(new Runnable() {
		public void run() {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"想吃虾片");
		}
		
		});
		//线程池任务2
		s.execute(new Runnable() {
			public void run() {
				System.out.println(Thread.currentThread().getName()+"想吃呀土豆");
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				}
				
			}
			
			});
		//线程池任务3
		s.execute(new Runnable() {
			public void run() {
				System.out.println(Thread.currentThread().getName()+"想吃小蛋糕");
			}
			
			});
		//线程池任务4
		s.execute(new Runnable() {
			public void run() {
				System.out.println(Thread.currentThread().getName()+"想吃锅巴");
			}
			
			});
		//线程池任务5
		s.execute(new Runnable() {
			public void run() {
				System.out.println(Thread.currentThread().getName()+"想吃小面包");
			}
			
			});

	}

}

 

 结果:共有五个任务,但线程池规定只能创建两个长度的线程,所以线程1和线程2那个线程先空闲,那个线程给排队的任务3、4、5使用。

3.单线程池

效果与定长线程池效果一致, 创建时传入数值1即可 

 执行流程:  1. 判断线程池 的那个线程 是否空闲

                   2. 空闲则使用 

                   4. 不空闲,则等待 池中的单个线程空闲后 使用

package dan;

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

public class Demo_4 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
        //创建线程池,长度为1
	ExecutorService s	= Executors.newSingleThreadExecutor(1);
//创建任务1
	s.execute(new Runnable() {
		public void run() {
			System.out.println(Thread.currentThread().getName()+"线程");
		}
	});
//创建任务2
	s.execute(new Runnable() {
		public void run() {
			System.out.println(Thread.currentThread().getName()+"线程2");
		}
	});

	}

}

 结果:线程池规定只可以创建一个线程,所以两个任务都用线程1

 4. 周期性任务定长线程池

执行流程: 1. 判断线程池是否存在空闲线程

                 2. 存在则使用

                 3. 不存在空闲线程,且线程池未满的情况下,则创建线程 并放入线程池, 然后使用

                 4. 不存在空闲线程,且线程池已满的情况下,则等待线程池存在空闲线程

 周期性任务执行时:  定时执行, 当某个时机触发时, 自动执行某任务 .

两个方法实现周期:方法一:schedule:定时执行一次任务

                               方法二:scheduleAtFixedRate:周期性执行任务

具体使用方法放代码

package zhouqi;

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

public class Demo_3 {

	public static void main(String[] args) {
	 ScheduledExecutorService s =Executors.newScheduledThreadPool(2);//创建两个长度的线程池
//方法一:schedule:定时执行一次任务
//       参数一:定时执行的任务
//       参数二:时长数字
//       参数三:时长数字的时长单位TimeUnit的常量指定
		s.schedule(new Runnable() {
			public void run() {
				System.out.println(Thread.currentThread().getName()+"线程");
			}
		},3,TimeUnit.SECONDS);
//		方法二:scheduleAtFixedRate:周期性执行任务
//		     参数一:任务
//		     参数二:延迟时长数字(第一次执行在什么时间以后)
//		     参数三:周期时长数字(每隔多久执行一次)
//		     参数四:时长数字的单位

		     s.scheduleAtFixedRate(new Runnable() {
			public void run() {
				System.out.println(Thread.currentThread().getName()+"线程2");
			}
		},5,1,TimeUnit.SECONDS);

	}
	

}

 结果:3s线程出现,然后线程2一秒出现一次。

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/962972.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号