线程池与队列


 线程池的作用:

线程池作用就是限制系统中执行线程的数量。
     根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;否则进入等待队列。

为什么要用线程池:

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

2.可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。

 

Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService。

 线程池与队列_第1张图片

 

 线程池与队列_第2张图片

 

 java多线程总结:线程池的原理及实现-

摘自--http://blog.csdn.net/touch_2011/article/details/6914468/

 

BlockingQueue的基本概要

--------------------摘自--http://wsmajunfeng.iteye.com/blog/1629354-----------------------------------

在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全传输数据的问题。通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利。

 

1.BlockingQueue的核心方法
放入数据:
offer(anObject):表示如果可能的话,anObject加到BlockingQueue,即如果BlockingQueue可以容纳,
    则返回true,否则返回false.(本方法不阻塞当前执行方法的线程)
offer(E o, long timeout, TimeUnit unit),可以设定等待的时间,如果在指定的时间内,还不能往队列中
    加入BlockingQueue,则返回失败。
put(anObject):anObject加到BlockingQueue,如果BlockQueue没有空间,则调用此方法的线程被阻断
    直到BlockingQueue里面有空间再继续.
获取数据:
poll(time):取走BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,
    取不到时返回null;
poll(long timeout, TimeUnit unit):从BlockingQueue取出一个队首的对象,如果在指定时间内,
    队列一旦有数据可取,则立即返回队列中的数据。否则知道时间超时还没有数据可取,返回失败。
take():取走BlockingQueue里排在首位的对象,BlockingQueue为空,阻断进入等待状态直到
BlockingQueue有新的数据被加入
drainTo():一次性从BlockingQueue获取所有可用的数据对象(还可以指定获取数据的个数), 
    通过该方法,可以提升获取数据效率;不需要多次分批加锁或释放锁。

 

2.BlockingQueue成员详细介绍

ArrayBlockingQueue,  基于数组的阻塞队列实现

LinkedBlockingQueue,基于链表的阻塞队列

-----------深入剖析java并发之阻塞队列LinkedBlockingQueue与ArrayBlockingQueue-----------

DelayQueue中的元素只有当其指定的延迟时间到了,才能够从队列中获取到该元素

PriorityBlockingQueue,  基于优先级的阻塞队列

SynchronousQueue一种无缓冲的等待队列,类似于无中介的直接交易

 

 

 

LinkedBlockingQueue

 

LinkedBlockingQueue是一个由链表实现的有界队列阻塞队列,但大小默认值为Integer.MAX_VALUE,所以我们在使用LinkedBlockingQueue时建议手动传值,为其提供我们所需的大小,避免队列过大造成机器负载或者内存爆满等情况

LinkedBlockingQueue队列是按 FIFO(先进先出)排序元素。队列的头部是在队列中时间最长的元素,队列的尾部是在队列中时间最短的元素,新元素插入到队列的尾部,而队列执行获取操作会获得位于队列头部的元素。

LinkedBlockingQueue内部分别使用了takeLock putLock对并发进行控制,也就是说,添加和删除操作并不是互斥操作,可以同时进行,这样也就可以大大提高吞吐量。这里再次强调如果没有给LinkedBlockingQueue指定容量大小,其默认值将是Integer.MAX_VALUE,如果存在添加速度大于删除速度时候,有可能会内存溢出

 

40Java多线程问题总结

http://blog.csdn.net/hiphopc/article/details/76834267

你可能感兴趣的:(将技术进行到底)