线程池的创建

举报
小高先生 发表于 2022/05/23 19:00:37 2022/05/23
【摘要】 什么是线程池以及创建线程池的方法

一、线程池

  首先概括一下线程池的概念,线程池相当于一个包装袋,袋子里有多个线程,在没有任务时,这些线程都是睡眠的,当有任务需要执行某个程序时,会调用相应的线程,被调用的线程会醒,执行过后继续睡眠。系统可以同时调用多个线程。

  通过线程池可以启动多线程,Executors的工具类可以创建线程。线程池的有以下几个有点:

  • 提高系统响应速度,当有任务时,复用已存在的线程,无需等待新的线程创建就可以立即执行任务
  • 降低系统资源消耗,复用已存在的线程,降低了新建和销毁线程的损耗
  • 方便线程管控,因为线程如果无限制创建,会占用过多的内存,并且造成cpu切换过渡

二、创建线程池

1.FixThreadPool(int n)固定大小的线程池

public class FixThreadPoolTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//创建固定大小线程的线程池
		ExecutorService ex = Executors.newFixedThreadPool(3);
		//用线程池执行任务
		for(int i = 0;i<3;i++) {
			ex.submit(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					for(int j = 0;j<10;j++) {
						System.out.println(Thread.currentThread().getName()+" "+j);
					}
				}
				
			});
	    }
//		ex.submit(new Runnable() {
//
//			@Override
//			public void run() {
//				// TODO Auto-generated method stub
//				for(int j = 0;j<10;j++) {
//					System.out.println(Thread.currentThread().getName()+" "+j);
//				}
//			}
//			
//		});只创建一个线程
		//关闭线程池,会把原先的任务执行完,但不会再执行新的任务
		ex.shutdown();
//通过结果表明,三个线程一共要执行5次,每个线程执行次数是随机的

2.SingleThreadPoolExcutor单线程池

  单线程池只能创建一个线程,优点是能够串行执行任务,保证任务执行顺序按照任务提交顺序

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

public class SingleThreadExecutor {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ExecutorService ex = Executors.newSingleThreadExecutor();
		for(int i = 0;i<5;i++) {
			ex.submit(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					for(int j = 0;j<10;j++) {
						System.out.println(Thread.currentThread().getName()+" "+j);
					}
				}
				
			});
		}
		ex.shutdown();
		
		
	}
	

}

3.CashedThreadPool()缓存线程池

  可以创建多个线程,数量不固定,线程最大值是int类型的最大值。当没有可用线程时,可以创建新的线程。

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

public class CashedThreadPoolTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ExecutorService ex =Executors.newCachedThreadPool();
		for(int i = 0;i<5;i++) {
			ex.submit(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					for(int j = 0;j<10;j++) {
						System.out.println(Thread.currentThread().getName()+" "+j);
					}
				}
				
			});
		}
		ex.shutdown();
		//需要执行5次线程任务,根据结果表明,创建了五个线程,5个线程每个都执行一遍for循环
	}

}

4.newScheduledThreadPool()创建一个周期性的线程池,支持定时及周期性执行任务

传递的是核心线程数,不是固定线程数。核心线程数是线程池维护的最小线程数,不会被回收

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

public class ScheduleThreadPoolTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
		scheduledThreadPool.scheduleAtFixedRate(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				System.out.println(Thread.currentThread().getName()+"执行"+new Date());
			}
			
		}, 5, 3,  TimeUnit.SECONDS);
	}

}

5.newWorkStealingPool新的线程池类ForkJoinPool扩展

JDK8之后新出的线程池类,之前的线程池类中的线程共享任务队列。在这个线程池中,每一个下次线程都有自己的队列,会造成CPU负载不均衡,可能有一个线程执行的任务过重。当线程发现自己没有任务时,回去其他线程中拿到任务,这样节省了执行任务的时间

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

public class NewWorkStealingPoolTest {

	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub
		System.out.println("--start--");
		ExecutorService executorService = Executors.newWorkStealingPool();
		for(int i = 0;i<10;i++) {
			executorService.submit(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					for(int j = 0;j<5;j++) {
						System.out.println(Thread.currentThread().getName()+" "+j);
					}
					
				}
				
			});
		
		}
	Thread.sleep(3000);//让主线程等待3秒,等子线程执行完任务
	System.out.println("--end--");
	//如果一个线程分配到了一个很大的任务,会把任务分成多个小任务再分配给各个线程,小任务执行完最后把结果合并
	}

}

根据结果表明,每次运行后,创建的线程数是不固定的,可能3个也可能4个

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。