• 目的

        了解线程池的知识后,写个线程池实例,熟悉多线程开发,建议看jdk线程池源码,跟大师比,才知道差距啊O(∩_∩)O


  • 线程池类
 package thread.pool2;

 import java.util.LinkedList;

 public class ThreadPool {
//最大线程数
private int maxCapacity;
//初始线程数
private int initCapacity;
//当前线程数
private int currentCapacity;
//线程池需要执行的任务
private LinkedList<Task> tasks;
//当前处于等待的线程数
private int waitThreadNum = 0;
//线程池中线程数超过初始数量时,此时有线程执行完任务,但是没有后续的任务执行,则会等待一段时间后,该线程才销毁
//destroyTime小于或等于0时,线程立即消费,大于0,则等待设置的时间
private int destroyTime = 0; public ThreadPool(int initCapacity,int maxCapacity, int destroyTime) {
if(initCapacity > maxCapacity) {
//初始线程数不能超过最大线程数,当然此处可以抛出异常,提示不允许这么设置
initCapacity = maxCapacity;
}
this.maxCapacity = maxCapacity;
this.initCapacity = initCapacity;
this.currentCapacity = initCapacity;
this.tasks = new LinkedList<Task>();
this.waitThreadNum = initCapacity;
this.destroyTime = destroyTime;
}
/**
* 向线程池中添加任务,如果线程数不够,则增加线程数,但线程数总量不能超过给定的最大线程数
* @param task
*/
public synchronized void addTask(Task task) {
tasks.add(task);
addThread();
notifyAll();
}
/**
* 从线程池中取出任务,如果没有任务,则当前线程处于等待状态
* @return
* @throws InterruptedException
*/
public synchronized Task getTask() throws InterruptedException {
while(tasks.isEmpty()) {
wait();
}
//取出第一个任务的同时将第一个任务移除
return tasks.pollFirst();
}
/**
* 判断线程池中任务列表是否为空
* @return
*/
public synchronized boolean isEmpty() {
return tasks.isEmpty();
}
/**
* 活跃线程数加1
*/
public synchronized void addWaitThreadNum(int num) {
waitThreadNum += num;
}
/**
* 活跃线程数减1
*/
public synchronized void reduceWaitThreadNum(int num) {
waitThreadNum -= num;
} /**
* 启动线程池
*/
public void execute() {
System.out.println(initCapacity);
for(int i = 0; i < initCapacity; i++) {
(new Thread(new InnerThread(this, "thread"+ i))).start();
}
}
/**
* 如果当前线程数大于初始线程数,则关闭当前线程,否则当前线程处于等待状态
* @return
* @throws InterruptedException
*/
public synchronized boolean waitOrClose(int tmp) throws InterruptedException {
System.out.println(currentCapacity + ":" + initCapacity);
//线程退出前,等待一段时间,防止线程频繁创建和销毁线程
if(destroyTime > 0) {
wait(destroyTime);
}
if(currentCapacity > initCapacity && tasks.isEmpty()) {
currentCapacity--;
System.out.println("任务执行完后,当前线程数:" + currentCapacity);
return false;
}
System.out.println("线程等待结束");
addWaitThreadNum(tmp);
wait();
return true;
} /**
* 当线程池内线程数不够时,如果有任务在等待处理,同时当前线程都处于非等待状态,
* 则增加线程池中线程数,但不能超过线程池中最大线程数
*/
public synchronized void addThread() {
System.out.println("当前线程数:" + currentCapacity + "最大线程数:" + maxCapacity + "等待线程数" + waitThreadNum);
if(currentCapacity < maxCapacity && waitThreadNum == 0) {
//每添加一个线程,当前线程数加1
currentCapacity++;
//每添加一个线程,相当于线程池中多了一个等待的线程
waitThreadNum++;
System.out.println("当前线程数为:" + currentCapacity);
new Thread(new InnerThread(this, "thread" + (currentCapacity-1))).start();
}
}
/**
* 线程池中单个线程对象
* @author yj
*
*/
private class InnerThread implements Runnable { private ThreadPool threadPool;
private String threadName; public InnerThread(ThreadPool threadPool, String threadName) {
this.threadPool = threadPool;
this.threadName = threadName;
} @Override
public void run() {
try {
while(true){
int addWait = 0;
int resuceWait = 1;
//不等于空,则处理任务
while(!threadPool.isEmpty()) {
threadName = Thread.currentThread().getName();
reduceWaitThreadNum(resuceWait);
Task task = threadPool.getTask();
task.execute(threadName);
try {
Thread.sleep(9000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(threadName + "对"+task.getTaskName()+"+任务进行了处理");
//只有处理任务后回到等待状态的线程才将waitThreadNum加1
addWait = 1;
//如果不跳出循环,则等待线程数不减少
resuceWait = 0;
}
//等于空,则等待任务或关闭当前线程
if(threadPool.waitOrClose(addWait)) {
System.out.println(threadName + "处于等待状态");
continue;
}
//关闭线程
break;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

  • 任务类
 package thread.pool2;

 public class Task{

     private String taskName;

     public String getTaskName() {
return taskName;
} public Task(String taskName) {
this.taskName = taskName;
} public void execute(String threadName) {
System.out.println(threadName + "开始执行任务为" + taskName);
/*try {
Thread.sleep(9000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
System.out.println(threadName + "执行" + taskName + "任务完成");
} }

  • 测试类
 package thread.pool2;

 public class ThreadPoolTest {

     public static void main(String[] args) {
ThreadPool threadPool = new ThreadPool(3, 10, 1100);
threadPool.execute();
for(int i = 0; i < 50; i++) {
int random = (int) (Math.random() * 1000);
threadPool.addTask(new Task("task"+random));
/*try {
//每个1秒向线程池中添加任务
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
}
} }

java线程池实例的更多相关文章

  1. JAVA四种线程池实例

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗?   Java   1 2 3 4 5 6 7 new Thread(new Runnable() {        ...

  2. java 线程池ThreadPoolExecutor 如何与 AsyncTask() 组合使用。

    转载请声明出处谢谢!http://www.cnblogs.com/linguanh/ 这里主要使用Executors中的4种静态创建线程池实例方法中的 newFixedThreadPool()来举例讲 ...

  3. Java线程池使用说明

    Java线程池使用说明 转自:http://blog.csdn.net/sd0902/article/details/8395677 一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极 ...

  4. 四种Java线程池用法解析

    本文为大家分析四种Java线程池用法,供大家参考,具体内容如下 http://www.jb51.net/article/81843.htm 1.new Thread的弊端 执行一个异步任务你还只是如下 ...

  5. Java线程池应用

    Executors工具类用于创建Java线程池和定时器. newFixedThreadPool:创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程.在任意点,在大多数 nThread ...

  6. [转 ]-- Java线程池使用说明

    Java线程池使用说明 原文地址:http://blog.csdn.net/sd0902/article/details/8395677 一简介 线程的使用在java中占有极其重要的地位,在jdk1. ...

  7. Java线程池学习

    Java线程池学习 Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java ...

  8. java线程池的使用与详解

    java线程池的使用与详解 [转载]本文转载自两篇博文:  1.Java并发编程:线程池的使用:http://www.cnblogs.com/dolphin0520/p/3932921.html   ...

  9. java线程池分析和应用

    比较 在前面的一些文章里,我们已经讨论了手工创建和管理线程.在实际应用中我们有的时候也会经常听到线程池这个概念.在这里,我们可以先针对手工创建管理线程和通过线程池来管理做一个比较.通常,我们如果手工创 ...

随机推荐

  1. python 文件操作: 文件操作的函数, 模式及常用操作.

    1.文件操作的函数: open("文件名(路径)", mode = '模式', encoding = "字符集") 2.模式: r , w , a , r+ , ...

  2. UVa 122 Trees on the level(二叉树层序遍历)

    Trees are fundamental in many branches of computer science. Current state-of-the art parallel comput ...

  3. 【环境配置】本地配置sublime text以及和远程linux设置sftp

    工具: sublime text 2(mac版) 远程linux(centos 7系) securCRT(for mac) [本地安装并配置securCRT(for mac)] 关于配置: 1.解决终 ...

  4. nginx配置websocket

    有时候我们需要给websocket服务端做一下nginx的配置,比如需要给websocket服务端做负载均衡,或者,有些系统要求访问websocket的时候不能带端口,这时候我们就需要用nginx来进 ...

  5. swift - 16进制颜色扩展(1.支持# 2.支持不带# , 3支持带0X)

    /** * 设置16进制颜色: * 可识别类型 * 1:有# * 2:没有# * 3:含有0X */ extension UIColor{ class func hexadecimalColor(he ...

  6. shell中颜色的设置

    linux启动后环境变量加载的顺序为:etc/profile → /etc/profile.d/*.sh → ~/.bash_profile → ~/.bashrc → [/etc/bashrc] 想 ...

  7. 在eclipse上写代码的时候,tomcat突然不能用了,重启都是闪一下就关了

    严重: A child container failed during start 严重: The required Server component failed to start so Tomca ...

  8. 关于map::erase的使用说明

    C++ 中经常使用的容器类有vector,list,map.其中vector和list的erase都是返回迭代器,但是map就比较不一样. 当在循环体中使用map::erase语句时,为了能够在任何机 ...

  9. Django+Uwsgi+Nginx部署

    一 uwsgi介绍 uWSGI是一个Web服务器,它实现了WSGI协议,uwsgi, http等协议. Nginx中HttpUwsgiMoule的作用是与uWSGI服务器进行交换 1 WSGI是一种W ...

  10. 完全卸载jdk

    完全卸载jdk  如(卸载jdk1.7.0_80),  当卸载jdk时出现删除信息不全,导致无法安装,可通过此方法实现完全卸载. 1.打开系统运行输入regedit(注册表)分别查找以下路径  (1) ...