多线程简单实例(3)线程池

为什么要用线程池?

每次用线程的时候都去new一个,不麻烦么。如果线程用到较少可以。当需要大量用到线程时,频繁的创建线程,而且创建线程和销毁带来的开销也会随之增多。

线程池就像一个执行器。而我们需要执行的业务逻辑,在我们编写的实现了Runnable接口的run方法里面。

需要执行就扔到线程池里,我只要保证我的业务逻辑在run里面已经实现了。执行找线程池这个代工。

线程池ThreadPoolExecutor类,下面是该类的构造方法。

public class ThreadPoolExecutor extends AbstractExecutorService {
    .....
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue);

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
        BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
    ...
}

主要参数介绍:

corePoolSize:核心线程数
maximumPoolSize:最大线程数(可以想象成cpu中的超超频)
keepAliveTime:线程无任务存活时间(一般情况下,当前线程数poolSize大于corePoolSize时,会销毁空闲时间大于keepAliveTime的线程,直到当前线程数不大于corePoolSize)
unit:keepAliveTime的单位(
TimeUnit.DAYS;               //天
TimeUnit.HOURS;             //小时
TimeUnit.MINUTES;           //分钟
TimeUnit.SECONDS;           //秒
TimeUnit.MILLISECONDS;      //毫秒
TimeUnit.MICROSECONDS;      //微妙
TimeUnit.NANOSECONDS;       //纳秒
)

BlockingQueue<Runnable>:缓存队列中允许最大的任务线程数(当线程数大于maxnumPoolSize时,将加入到缓存队列中)
ThreaPoolExecutor的一些方法:execute():线程池加入线程submit():线程池加入线程(和execute方法一样,只不过会返回一个参数。ps:其实submit内部也是调用了execute方法)shutdown():关闭线程池(若线程池和缓存中还有未执行完的线程,则会继续执行,执行完清空线程池。)shutdownNow():马上关闭线程池(若线程池中还有未执行完的线程,则会抛出异常)

简单的例子:
package code.thread;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

//线程池
public class ThreadPool {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MICROSECONDS,
                new ArrayBlockingQueue<Runnable>(5));
        for(int i=0;i<15;i++){
            threadPool.execute(new Task(i));
            System.out.println("线程池中的线程数:"+threadPool.getPoolSize()+"  队列中等待的线程数:"+
            threadPool.getQueue().size()+"  已执行完的线程数:"+threadPool.getCompletedTaskCount());
        }
        {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        System.out.println("线程池中的线程数:"+threadPool.getPoolSize()+"  队列中等待的线程数:"+
                threadPool.getQueue().size()+"  已执行完的线程数:"+threadPool.getCompletedTaskCount());

        }
        threadPool.shutdown();

    }
}

class Task implements Runnable {
    private int i;
    public Task(int i) {
        this.i = i;
    }
    @Override
    public void run() {
        System.out.println("task:"+i+"执行");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("task:"+i+"执行结束");

    }

}

执行结果:

task:0执行
线程池中的线程数:1 队列中等待的线程数:0 已执行完的线程数:0
线程池中的线程数:2 队列中等待的线程数:0 已执行完的线程数:0
task:1执行
线程池中的线程数:3 队列中等待的线程数:0 已执行完的线程数:0
task:2执行
线程池中的线程数:4 队列中等待的线程数:0 已执行完的线程数:0
task:3执行
线程池中的线程数:5 队列中等待的线程数:0 已执行完的线程数:0
task:4执行
线程池中的线程数:5 队列中等待的线程数:1 已执行完的线程数:0
线程池中的线程数:5 队列中等待的线程数:2 已执行完的线程数:0
线程池中的线程数:5 队列中等待的线程数:3 已执行完的线程数:0
线程池中的线程数:5 队列中等待的线程数:4 已执行完的线程数:0
线程池中的线程数:5 队列中等待的线程数:5 已执行完的线程数:0
线程池中的线程数:6 队列中等待的线程数:5 已执行完的线程数:0
task:10执行
线程池中的线程数:7 队列中等待的线程数:5 已执行完的线程数:0
task:11执行
task:12执行
线程池中的线程数:8 队列中等待的线程数:5 已执行完的线程数:0
线程池中的线程数:9 队列中等待的线程数:5 已执行完的线程数:0
task:13执行
task:14执行
线程池中的线程数:10 队列中等待的线程数:5 已执行完的线程数:0
task:0执行结束
task:2执行结束
task:5执行
task:1执行结束
task:6执行
task:3执行结束
task:8执行
task:4执行结束
task:9执行
task:13执行结束
task:7执行
task:10执行结束
task:11执行结束
task:12执行结束
task:14执行结束
task:5执行结束
task:6执行结束
task:7执行结束
task:9执行结束
task:8执行结束
线程池中的线程数:5 队列中等待的线程数:0 已执行完的线程数:15

 
时间: 2024-10-03 13:22:58

多线程简单实例(3)线程池的相关文章

java线程及操作实例,线程池简单例子

java io.集合.线程.字符串.gc.jvm可谓是java中的最基本的知识,尤其是线程操作复杂,相应难懂,要想java基础知识扎实,上面提到的几个方面的知识点都要精通,这样方可以称自己掌握java方面基础知识. 总结一下java线程知识,平时接触过线程,尤其是在android开发中,线程可谓是无处不在,稍有不注意就会报错.在java中线程也是无处不在,main就是一个线程,只不过被包装好了,一般接触不到. 我的无数次的复习经历告诉我,学习知识最快,最深刻的方法就是从解题开始,不要先看概念,遇

C#多线程之旅(3)——线程池

v博客前言 先交代下背景,写<C#多线程之旅>这个系列文章主要是因为以下几个原因:1.多线程在C/S和B/S架构中用得是非常多的;2.而且多线程的使用是非常复杂的,如果没有用好,容易造成很多问题. v写在前面 多线程,有利也有弊,使用需谨慎. v正文开始 原文地址:C#多线程之旅(3)——线程池 C#多线程之旅目录: C#多线程之旅(1)——介绍和基本概念 C#多线程之旅(2)——创建和开始线程 C#多线程之旅(3)——线程池 C#多线程之旅(4)——同步本质 ...... 一.介绍 无论你什

【转载】5天不再惧怕多线程——第五天 线程池

说到多线程,不可不说线程池,C#中关于池的概念很多,今天来整理下ThreadPool的使用. 是的,如果你很懒,如果你的执行任务比较短,如果你不想对线程做更精细的控制,那么把这些繁琐的东西丢给线程池吧. 一:ThreadPool 好了,下面看看TheadPool下有哪些常用的方法. 1:GetMaxThreads,GetMinThreads 首先我们肯定好奇线程池到底给我们如何控制线程数,下面就具体的看一看. 1 class Program 2 { 3 static void Main(stri

Java 多线程 简单实例 (消费者与生成者)的关系

PS::线程这套东西在PHP里完全是不存在的概念,有待进一步的学习: PS::这个实例是根据书本上的知识进行扩展的,理解程度50%左右吧! 1.定义生产消费环境 package second; public class Queue { int value = 0; boolean isEmpty = true; /** * 生产者 * @param v */ public synchronized void put(int v){ if(!isEmpty){//如果存在数据没有被消费 try{

JAVA程序设计(18.1)----- 1多线程轮流打印 线程调度 线程池 synchronized wait notify 内部类

1.两个线程 一个打印A 一个打印B 另两个线程轮流进行打印工作 多线程初级应用 线程调度  线程池(预先建立N个线程,需要的程序直接调用,执行完毕后归还回线程池,典型的以空间换时间 synchronized wait notify  内部类使用 package com.lovo; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 类:测试 wait notify 用

C# 多线程的自动管理(线程池) 基于Task的方式

C# 多线程的自动管理(线程池) 在多线程的程序中,经常会出现两种情况:    1. 应用程序中线程把大部分的时间花费在等待状态,等待某个事件发生,然后给予响应.这一般使用 ThreadPool(线程池)来解决.     2. 线程平时都处于休眠状态,只是周期性地被唤醒.这一般使用 Timer(定时器)来解决. ThreadPool 类提供一个由系统维护的线程池(可以看作一个线程的容器),该容器需要 Windows 2000 以上系统支持,因为其中某些方法调用了只有高版本的Windows 才有的

java多线程详解(7)-线程池的使用

在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, 这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间. 这个是时候我们需要使用线程池技术创建多线程. 本文目录大纲: 一.Java中的ThreadPoolExecutor类 二.深入剖析线程池实现原理 三.使用示例 四.如何合理配置线程池的大小 一.Java中的ThreadPoolExecutor类 jav

java多线程(四)-自定义线程池

当我们使用 线程池的时候,可以使用 newCachedThreadPool()或者 newFixedThreadPool(int)等方法,其实我们深入到这些方法里面,就可以看到它们的是实现方式是这样的. 1 public static ExecutorService newCachedThreadPool() { 2 return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 3 60L, TimeUnit.SECONDS, 4 new Synchro

一个简单的python线程池框架

初学python,实现了一个简单的线程池框架,线程池中除Wokers(工作线程)外,还单独创建了一个日志线程,用于日志的输出.线程间采用Queue方式进行通信. 代码如下: 1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 __author__ = "pandaychen" 5 6 import Queue 7 import sys 8 import os 9 import threading 10 import time 11