java线程池实例

  • 目的

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


  • 线程池类
  1 package thread.pool2;
  2
  3 import java.util.LinkedList;
  4
  5 public class ThreadPool {
  6     //最大线程数
  7     private int maxCapacity;
  8     //初始线程数
  9     private int initCapacity;
 10     //当前线程数
 11     private int currentCapacity;
 12     //线程池需要执行的任务
 13     private LinkedList<Task> tasks;
 14     //当前处于等待的线程数
 15     private int waitThreadNum = 0;
 16     //线程池中线程数超过初始数量时,此时有线程执行完任务,但是没有后续的任务执行,则会等待一段时间后,该线程才销毁
 17     //destroyTime小于或等于0时,线程立即消费,大于0,则等待设置的时间
 18     private int destroyTime = 0;
 19
 20     public ThreadPool(int initCapacity,int maxCapacity, int destroyTime) {
 21         if(initCapacity > maxCapacity) {
 22             //初始线程数不能超过最大线程数,当然此处可以抛出异常,提示不允许这么设置
 23             initCapacity = maxCapacity;
 24         }
 25         this.maxCapacity = maxCapacity;
 26         this.initCapacity = initCapacity;
 27         this.currentCapacity = initCapacity;
 28         this.tasks = new LinkedList<Task>();
 29         this.waitThreadNum = initCapacity;
 30         this.destroyTime = destroyTime;
 31     }
 32     /**
 33      * 向线程池中添加任务,如果线程数不够,则增加线程数,但线程数总量不能超过给定的最大线程数
 34      * @param task
 35      */
 36     public synchronized void addTask(Task task) {
 37         tasks.add(task);
 38         addThread();
 39         notifyAll();
 40     }
 41     /**
 42      * 从线程池中取出任务,如果没有任务,则当前线程处于等待状态
 43      * @return
 44      * @throws InterruptedException
 45      */
 46     public synchronized Task getTask() throws InterruptedException {
 47         while(tasks.isEmpty()) {
 48             wait();
 49         }
 50         //取出第一个任务的同时将第一个任务移除
 51         return tasks.pollFirst();
 52     }
 53     /**
 54      * 判断线程池中任务列表是否为空
 55      * @return
 56      */
 57     public synchronized boolean isEmpty() {
 58         return tasks.isEmpty();
 59     }
 60     /**
 61      * 活跃线程数加1
 62      */
 63     public synchronized void addWaitThreadNum(int num) {
 64         waitThreadNum += num;
 65     }
 66     /**
 67      * 活跃线程数减1
 68      */
 69     public synchronized void reduceWaitThreadNum(int num) {
 70         waitThreadNum -= num;
 71     }
 72
 73     /**
 74      * 启动线程池
 75      */
 76     public void execute() {
 77         System.out.println(initCapacity);
 78         for(int i = 0; i < initCapacity; i++) {
 79             (new Thread(new InnerThread(this, "thread"+ i))).start();
 80         }
 81     }
 82     /**
 83      * 如果当前线程数大于初始线程数,则关闭当前线程,否则当前线程处于等待状态
 84      * @return
 85      * @throws InterruptedException
 86      */
 87     public synchronized boolean waitOrClose(int tmp) throws InterruptedException {
 88         System.out.println(currentCapacity + ":" + initCapacity);
 89         //线程退出前,等待一段时间,防止线程频繁创建和销毁线程
 90         if(destroyTime > 0) {
 91             wait(destroyTime);
 92         }
 93         if(currentCapacity > initCapacity && tasks.isEmpty()) {
 94             currentCapacity--;
 95             System.out.println("任务执行完后,当前线程数:" + currentCapacity);
 96             return false;
 97         }
 98         System.out.println("线程等待结束");
 99         addWaitThreadNum(tmp);
100         wait();
101         return true;
102     }
103
104     /**
105      * 当线程池内线程数不够时,如果有任务在等待处理,同时当前线程都处于非等待状态,
106      * 则增加线程池中线程数,但不能超过线程池中最大线程数
107      */
108     public synchronized void addThread() {
109         System.out.println("当前线程数:" + currentCapacity + "最大线程数:" + maxCapacity + "等待线程数" + waitThreadNum);
110         if(currentCapacity < maxCapacity && waitThreadNum == 0) {
111             //每添加一个线程,当前线程数加1
112             currentCapacity++;
113             //每添加一个线程,相当于线程池中多了一个等待的线程
114             waitThreadNum++;
115             System.out.println("当前线程数为:" + currentCapacity);
116             new Thread(new InnerThread(this, "thread" + (currentCapacity-1))).start();
117         }
118     }
119     /**
120      * 线程池中单个线程对象
121      * @author yj
122      *
123      */
124     private class InnerThread implements Runnable {
125
126         private ThreadPool threadPool;
127         private String threadName;
128
129         public InnerThread(ThreadPool threadPool, String threadName) {
130             this.threadPool = threadPool;
131             this.threadName = threadName;
132         }
133
134         @Override
135         public void run() {
136             try {
137                 while(true){
138                     int addWait = 0;
139                     int resuceWait = 1;
140                     //不等于空,则处理任务
141                     while(!threadPool.isEmpty()) {
142                         threadName = Thread.currentThread().getName();
143                         reduceWaitThreadNum(resuceWait);
144                         Task task = threadPool.getTask();
145                         task.execute(threadName);
146                         try {
147                             Thread.sleep(9000);
148                         } catch (InterruptedException e) {
149                             e.printStackTrace();
150                         }
151                         System.out.println(threadName + "对"+task.getTaskName()+"+任务进行了处理");
152                         //只有处理任务后回到等待状态的线程才将waitThreadNum加1
153                         addWait = 1;
154                         //如果不跳出循环,则等待线程数不减少
155                         resuceWait = 0;
156                     }
157                     //等于空,则等待任务或关闭当前线程
158                     if(threadPool.waitOrClose(addWait)) {
159                         System.out.println(threadName + "处于等待状态");
160                         continue;
161                     }
162                     //关闭线程
163                     break;
164                 }
165             } catch (InterruptedException e) {
166                 e.printStackTrace();
167             }
168         }
169     }
170 }

  • 任务类

 1 package thread.pool2;
 2
 3 public class Task{
 4
 5     private String taskName;
 6
 7     public String getTaskName() {
 8         return taskName;
 9     }
10
11     public Task(String taskName) {
12         this.taskName = taskName;
13     }
14
15     public void execute(String threadName) {
16         System.out.println(threadName + "开始执行任务为" + taskName);
17         /*try {
18             Thread.sleep(9000);
19         } catch (InterruptedException e) {
20             e.printStackTrace();
21         }*/
22         System.out.println(threadName + "执行" + taskName + "任务完成");
23     }
24
25 }


  • 测试类

 1 package thread.pool2;
 2
 3 public class ThreadPoolTest {
 4
 5     public static void main(String[] args) {
 6         ThreadPool threadPool = new ThreadPool(3, 10, 1100);
 7         threadPool.execute();
 8         for(int i = 0; i < 50; i++) {
 9             int random = (int) (Math.random() * 1000);
10             threadPool.addTask(new Task("task"+random));
11             /*try {
12                 //每个1秒向线程池中添加任务
13                 Thread.sleep(1000);
14             } catch (InterruptedException e) {
15                 e.printStackTrace();
16             }*/
17         }
18     }
19
20 }

时间: 2024-10-24 11:50:17

java线程池实例的相关文章

Java学习(十):Java线程池实例

线程池可以解决两个不同问题:由于减少了每个任务调用的开销,它们通常可以在执行大量异步任务时提供增强的性能,并且还可以提供绑定和管理资源(包括执行任务集时使用的线程)的方法.每个 ThreadPoolExecutor 还维护着一些基本的统计数据,如完成的任务数. Java常用的线程池有四种.Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收).Executors.newFixedThreadPool(int)(固定大小线程池).Executors.ne

JAVA四种线程池实例

1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? Java 1 2 3 4 5 6 7 new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }).start(); 那你就out太多了,new Thread的弊端如下: a. 每次new Thread新建对象性能差. b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及

Java线程池应用

Executors工具类用于创建Java线程池和定时器. newFixedThreadPool:创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程.在任意点,在大多数 nThreads 线程会处于处理任务的活动状态.如果在所有线程处于活动状态时提交附加任务,则在有可用线程之前,附加任务将在队列中等待.如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要).在某个线程被显式地关闭之前,池中的线程将一直存在. 创建一个固定大小的线程池来执

Java线程池使用说明

Java线程池使用说明 一 简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后加入了java.util.concurrent包,这个包中主要介绍java中线程以及线程池的使用.为我们在开发中处理线程的问题提供了非常大的帮助. 二:线程池 线程池的作用: 线程池作用就是限制系统中执行线程的数量.     根 据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果:少

Java 线程池学习

Reference: <创建Java线程池>[1],<Java线程:新特征-线程池>[2], <Java线程池学习>[3],<线程池ThreadPoolExecutor使用简介>[4],<Java5中的线程池实例讲解>[5],<ThreadPoolExecutor使用和思考>[6] [1]中博主自己通过ThreadGroup实现一个线程池(挺方便理解的),使用的是jdk1.4版本,Jdk1.5版本以上提供了现成的线程池. [2]中介绍

JAVA线程池的分析和使用

http://www.infoq.com/cn/articles/java-threadPool/ 1. 引言 合理利用线程池能够带来三个好处.第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗.第二:提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行.第三:提高线程的可管理性.线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控.但是要做到合理的利用线程池,必须对其原理了如指掌. 2. 线程池

java线程池分析和应用

比较 在前面的一些文章里,我们已经讨论了手工创建和管理线程.在实际应用中我们有的时候也会经常听到线程池这个概念.在这里,我们可以先针对手工创建管理线程和通过线程池来管理做一个比较.通常,我们如果手工创建线程,需要定义线程执行对象,它实现的接口.然后再创建一个线程对象,将我们定义好的对象执行部分装载到线程中.对于线程的创建.结束和结果的获取都需要我们来考虑.如果我们需要用到很多的线程时,对线程的管理就会变得比较困难.我们手工定义线程的方式在时间和空间效率方面会存在着一些不足.比如说我们定义好的线程

Java线程池使用和分析(二) - execute()原理

相关文章目录: Java线程池使用和分析(一) Java线程池使用和分析(二) - execute()原理 execute()是 java.util.concurrent.Executor接口中唯一的方法,JDK注释中的描述是“在未来的某一时刻执行命令command”,即向线程池中提交任务,在未来某个时刻执行,提交的任务必须实现Runnable接口,该提交方式不能获取返回值.下面是对execute()方法内部原理的分析,分析前先简单介绍线程池有哪些状态,在一系列执行过程中涉及线程池状态相关的判断

Java线程池介绍

Java线程池介绍 2015-10-24 ImportNew (点击上方公号,可快速关注) 原文:allegro 译文:ImportNew - paddx 链接:http://www.importnew.com/16845.html 根据摩尔定律(Moore’s law),集成电路晶体管的数量差不多每两年就会翻一倍.但是晶体管数量指数级的增长不一定会导致 CPU 性能的指数级增长.处理器制造商花了很多年来提高时钟频率和指令并行.在新一代的处理器上,单线程程序的执行速率确实有所提高.但是,时钟频率