自定义线程池实现

摘要:
isAlive){51returnnull;52}53wait();54}55//否则,返回一条任务56returntaskQueue.removeFirst();57}5859/**60*关闭线程池,停止所有在运行的任务61*/62publicsynchronizedvoidclose(){63//如果线程池是活的64if{65//关闭66isAlive=false;//67//清空任务68taskQueue.clear();69interrupt();//关闭线程组里面的所有线程70}71}7273/**74*关闭线程池,不停止在运行的任务75*/76publicvoidjoin(){77synchronized{78isAlive=false;79notifyAll();80}81//执行未完成的任务82Thread[]threads=newThread[activeCount()];//创建池中的线程数量一致的数组83intcount=enumerate;//复制本线程池中的线程到刚才创建的线程数组84//然后依次执行线程数组中的线程85for{86try{87threads[i].join();//效果相当于执行88}catch{89ei.printStackTrace();90}91}92}9394publicclassPooledThreadextendsThread{9596/**97*创建线程的时候指定线程池98*@paramtg99*@paramthreadPoolName100*/101publicPooledThread(){102super;103}104105/**106*重写run方法107*/108publicvoidrun(){109while(!

线程池的特点:

1,迅速响应.

2,线程之间无优先级.

3,线程执行时间短,不阻塞其他任务.

4,线程不可绑定操作,不可被跟踪.

优点:

1,对象线程不用重复的创建与销毁,节省时间,资源.

2,可以对线程的数量进行控制.

案例

线程池类:

1 importjava.util.LinkedList;
2 
3 public class ThreadPool extendsThreadGroup {
4 
5     private boolean isAlive;//是否活着
6 
7     private LinkedList<Runnable> taskQueue;//任务队列
8 
9     private int threadID;//线程ID
10 
11     private static int threadPoolID;//线程池ID
12 
13     public ThreadPool(intthreadNums) {
14         super("线程池-" + (threadPoolID++));
15         setDaemon(true);//设置线程组为守护线程组
16         isAlive = true;//设置线程组的初始状态
17         taskQueue = new LinkedList<Runnable>();//初始化任务队列
18         for (int i = 0; i < threadNums; i++) {
19             //启动组中的线程(初始化线程,线程一直保持运行状态,不断地获取线程池里面的待执行任务)
20             newPooledThread().start();
21 }
22 }
23 
24     /**
25 * 运行任务的入口,线程安全(有序的到达线程池)
26 * 
27 * @paramtask
28      */
29     public synchronized voidrunTask(Runnable task) {
30         //如果线程池关闭状态,抛出异常
31         if (!isAlive) {
32             throw newIllegalStateException();
33 }
34         //如果任务不为null
35         if (task != null) {
36             //加入任务队列
37 taskQueue.add(task);
38             notify();//激活该方法上的其他线程之一
39 }
40 }
41 
42     /**
43 * 获取等待执行的任务,线程安全(保证一次获取一个,不重复)
44 * @return
45 * @throwsInterruptedException
46      */
47     protected synchronized Runnable getTask()throwsInterruptedException{
48         //当线程池没有可运行的任务时,并且线程池在工作状态,挂起线程池
49         while(taskQueue.size()==0){
50             if(!isAlive){
51                 return null;
52 }
53 wait();
54 }
55         //否则,返回一条任务
56         return(Runnable)taskQueue.removeFirst();
57 }
58     
59     /**
60 * 关闭线程池,停止所有在运行的任务
61      */
62     public synchronized voidclose(){
63         //如果线程池是活的
64         if(isAlive){
65             //关闭
66             isAlive= false;//
67             //清空任务
68 taskQueue.clear();
69             interrupt();//关闭线程组里面的所有线程(此方法不一定能够停止线程,只是更改了isInterrupted()方法的状态)
70 }
71 }
72     
73     /**
74 * 关闭线程池,不停止在运行的任务
75      */
76     public voidjoin(){
77         synchronized(this){
78             isAlive = false;
79 notifyAll();
80 }
81         //执行未完成的任务
82         Thread[] threads = new Thread[activeCount()];//创建池中的线程数量一致的数组
83         int count = enumerate(threads);//复制本线程池中的线程到刚才创建的线程数组
84         //然后依次执行线程数组中的线程
85         for(int i=0;i<count;i++){
86             try{
87                 threads[i].join();//效果相当于执行
88             }catch(InterruptedException ei){
89 ei.printStackTrace();
90 }
91 }
92 }
93     
94     public class PooledThread extendsThread{
95 
96         /**
97 * 创建线程的时候指定线程池
98 * @paramtg
99 * @paramthreadPoolName
100          */
101         publicPooledThread(){
102             super(ThreadPool.this,"线程(ID号)"+threadID++);
103 }
104         
105         /**
106 * 重写run方法
107          */
108         public voidrun(){
109             while(!isInterrupted()){
110                 Runnable task = null;
111                 try{
112                     task=getTask();
113                 } catch(Exception e) {
114 e.printStackTrace();
115 }
116                 if(task==null){
117                     return;
118 }
119                 try{
120                     System.out.println(this.getId());
121 task.run();
122                 } catch(Throwable e) {
123                     //处理异常
124                     uncaughtException(this,e);
125 }
126 }
127 }
128         
129         
130 }
131     
132     
133     
134 
135 }

测试方法:

public classTest {
    public static voidmain(String[] args){
        for(int i=0;i<args.length;i++){
            System.out.println(args[i]);
        }
        if(args.length!=2){
            System.out.println("测试自定义线程池开始");
            System.out.println("使用方法,两个参数[任务数,线程数]");
            System.out.println("任务数-int:需要执行的任务数");
            System.out.println("线程数-int:线程池初始化数量");
        }
        int numTasks = 20;
        int numThreads = 5;
        ThreadPool threadPool = newThreadPool(numThreads);
        for(int i=0;i<numTasks;i++){
            threadPool.runTask(createTask(i));
        }
        threadPool.join();
    }
    
    private static Runnable createTask(final inttaskID){
        return newRunnable() {
            
            @Override
            public voidrun() {
                System.out.println("任务"+taskID+"开始");
                try{
                    Thread.sleep(500);
                } catch(Exception e) {
                    e.printStackTrace();
                }
                System.out.println("任务"+taskID+"结束");
            }
        };
    }
    
}

免责声明:文章转载自《自定义线程池实现》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇springboot集成下,mybatis的mapper代理对象究竟是如何生成的不安全的直接对象引用:你的 ASP.NET 应用数据是否安全?下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C++11多线程编程系列-相关库函数使用

1、C++11 新标准中引入了多个头文件来支持多线程编程,分别是<atomic>,<thread>,<mutex>,<condition_variable>和<future>。 <atomic>:该头文主要声明了两个类, std::atomic 和 std::atomic_flag,另...

委托和多线程(一)

         定义:委托是一个类型安全的对象,它指向程序中另一个以后会被调用的方法(或多个方法)。通俗的说,委托是一个可以引用方法的对象,当创建一个委托,也就创建一个引用方法的对象,进而就可以调用那个方法,即委托可以调用它所指的方法。 委托的试用步骤: 1、定义委托:权限修饰符   delegate   返回值     委托名 (参数); 2、声明委托...

详解tomcat的连接数与线程池

前言 在使用tomcat时,经常会遇到连接数、线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector)。 在前面的文章详解Tomcat配置文件server.xml中写到过:Connector的主要功能,是接收连接请求,创建Request和Response对象用于和请求端交换数据;然后分配线程让Engine(也就是Ser...

python基础整理5——多进程多线程和协程

进程与线程 1.进程 我们电脑的应用程序,都是进程,假设我们用的电脑是单核的,cpu同时只能执行一个进程。当程序处于I/O阻塞的时候,CPU如果和程序一起等待,那就太浪费了,cpu会去执行其他的程序,此时就涉及到切换,切换前要保存上一个程序运行的状态,才能恢复,所以就需要有个东西来记录这个东西,就可以引出进程的概念了。 进程就是一个程序在一个数据集上的一次...

ManualResetEvent 与 AutoResetEvent 的理解和使用

在多线程开发中,时常用到ManualResetEvent 与AutoResetEvent 。 它们如同道路交通中的信号灯。两者之间有什么区别呢? 共同点: 均继承EventWaitHandle 接口,因此,均具有以下功能: Reset() //红灯 Set() //绿灯 WaitOne() // 等待信号 ManualResetEvent mre = ne...

多线程处理同一个List测试dome

package com.sysware.p2m.task.op.process; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; public class ThreadTese{ static cla...