黑马程序员_24 线程池



------------ASP.Net+Android+IO开发S.Net培训、期待与您交流! ----------



                                     线程池

线程池的作用:

     线程池作用就是限制系统中执行线程的数量。
     根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳

效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线

程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的

任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一

个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;

否则进入等待队列。

 

为什么要用线程池:

1:减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执

多个任务

2:可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为因

为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开

的越多,消耗的内存也就越大,最后死机)


线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存

放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线

程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复

创建线程对象所带来的性能开销,节省了系统的资源。 

要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚

的情况下,很有可能配置的线程池不是较优的,因此在Executors类里

面提供了一些静态工厂,生成一些常用的线程池。

标记一下比较重要的类:

ExecutorService:真正的线程池接口。

ScheduledExecutorService:能和Timer/TimerTask类似,解决那些需要任务重

                                     复执行的问题。

ThreadPoolExecutor:ExecutorService的默认实现。

ScheduledThreadPoolExecutor:

                   继承ThreadPoolExecutor的ScheduledExecutorService接口实现,

                   周期性任务调度的类实现。

要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,
很有可能配置的线程池不是较优的,因此在Executors类里面提供了一些静态工厂,
生成一些常用的线程池。


newSingleThreadExecutor:创建一个单线程的线程池。这个线程池只有一个线程在

                   工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因

                   为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务

                   的执行顺序按照任务的提交顺序执行。

newFixedThreadPool:创建固定大小的线程池。每次提交一个任务就创建一个线程,

                   直到线程达到 线程池的最大大小。线程池的大小一旦达到最大值就会保

                   持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新

                   线程。

newCachedThreadPool:创建一个可缓存的线程池。如果线程池的大小超过了处理

          任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任

              务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会

              对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够

              创建的最大线程大小。

newScheduledThreadPool:创建一个大小无限的线程池。此线程池支持定时以及周

              期性执行任务的需求。

newSingleThreadExecutor:创建一个单线程的线程池。此线程池支持定时以及周期

              性执行任务的需求。

例:单任务线程池:

//创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。 
ExecutorService pool = Executors.newSingleThreadExecutor(); 

例如张老师的7k面试题中用到的线程池

    //模拟车辆不断随机上路的过程       
        ExecutorService pool = Executors.newSingleThreadExecutor();  
        //新建单独的线程,返回线程池,给线程池提交一个任务,线程池就会挑选一个空闲的
        //线程来完成这个任务  
        /*Executors工具往往以S结尾的,里面多是静态方法。这个叫执行器 
        static ExecutorService |newSingleThreadExecutor()  
          创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。 
           
          newFixedThreadPool(int nThreads)参数为池中的线程数  
          创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。 
          意思是一上来就产生很多线程,这些线程封装为一个组里面,以后有任务的时候,
          线程池里哪个线程空闲就交予哪个线程来做 
          */  
          
          
          
        /*execute  | void execute(Runnable command) 
        在未来某个时间执行给定的命令。该命令可能在新的线程、已入池的线程或者
        正调用的线程中执行,这由 Executor 实现决定。 
        参数:command - 可运行的任务 
        意思是挑选某个线程来执行*/  
        pool.execute(new Runnable()  
          
        {  
            public void run()  
            {    
                for(int i=1;i<1000;i++)  
                {  
                    try  
                    {   

                        Thread.sleep((new Random().nextInt(10) + 1) * 1000);  
                    }   
                    catch (InterruptedException e)   
                    {  
                        e.printStackTrace();  
                    }  
                    vechicles.add(Road.this.name + "_" + i);  
                }                 
            }  
              
        });  
          
        // 周期性任务调度的类实现   
        ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);  
          
        timer.scheduleAtFixedRate(  
                new Runnable(){  
                    public void run()  
                    {     
                        if(vechicles.size()>0)  
                        {    
                            boolean lighted = Lamp.valueOf(Road.this.name).isLighted();  
                            if(lighted)  
                            {  
                                System.out.println(vechicles.remove(0) + " is traversing !");  
                            }  
                              
                        }  
                          
                    }  
                },  
                1,  //首次执行的延迟时间
                1,  //再过多长时间继续执行上一次任务。
                TimeUnit.SECONDS);//规定执行时间度量单位  
            /*scheduleAtFixedRate 计划固定频率来做这件事 
                   ScheduledFuture<?> scheduleAtFixedRate( 
                                     Runnable command, 
                                     long initialDelay, 
                                     long period, 
                                     TimeUnit unit)枚举类表示单元粒度的时间段 
                            创建并执行一个在给定初始延迟后首次启用的定期操作,
                            后续操作具有给定的周期; 
                            也就是将在 initialDelay 后开始执行,然后在 initialDelay
                            +period 后执行, 
                            接着在 initialDelay + 2 * period 后执行,依此类推。如果任务的
                            任何一个执行遇到异常, 则后续执行都会被取消。否则,只能通过执
                            行程序的取消或终止方法来终止该任务。 
                            如果此任务的任何一个执行要花费比其周期更长的时间,则将推迟后续执行,
                            但不会同时执行。 
                                                 
                        参数:command - 要执行的任务 
                              initialDelay - 首次执行的延迟时间 
                              period - 连续执行之间的周期 
                              unit - initialDelay 和 period 参数的时间单位 
                  schedule   给定延迟后操作一次*/      
    }  



------------ASP.Net+Android+IO开发S.Net培训、期待与您交流! ----------



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值