c3 Threads - Thread Pools and Executors
来源:互联网 发布:马云的淘宝怎么赚钱的 编辑:程序博客网 时间:2024/05/29 16:32
是不是线程越多越好呢?
在有I/O瓶颈的程序里,比如大部分网络程序,使用多线程可以提高性能,在一个程序block时,其他程序继续执行,以使cpu别闲着。但是,是不是线程越多越好呢?不是!因为使用多线程本身也是有成本的:创建、销毁线程需要VM销毁资源,需要垃圾回收器忙活,当一个小服务器不停的创建销毁了成百上千个线程时,这本身就是巨大的资源消耗;其次,更重要的是,线程间的切换!如果是cpu-bound的程序,那少切换会使程序更快的执行完!再者,最重要的是,虽然线程可以提高cpu使用率,但是cpu资源也是有限的,如果一味的spawn多的线程,那MIPS和Memory资源就全部花在线程管理上了。
java.util.concurrent中的类Executor可以很容易的管理thread,只需要把Runnable对象丢给pool,然后会得到一个Future对象,可用来查看task执行情况。
看个例子,现在要用java.util.zip.GZIPOutputStream压缩给定目录下的文件。
一方面,需要频繁的I/O操作,read和write。另一方面,压缩时又是cpu-intensive,所以不能创建太多的线程,这里用线程池非常合适。
class GZipRunnable implements Runnable { private final File input; public GZipRunnable(File input) { this.input = input; } @Override public void run() { // don't compress an already compressed file if (!input.getName().endsWith(".gz")) { File output = new File(input.getParent(), input.getName() + ".gz"); if (!output.exists()) { // Don't overwrite an existing file try ( // with resources; requires Java 7 InputStream in = new BufferedInputStream(new FileInputStream(input)); OutputStream out = new BufferedOutputStream( new GZIPOutputStream( new FileOutputStream(output))); ) { int b; while ((b = in.read()) != -1) out.write(b); out.flush(); } catch (IOException ex) { System.err.println(ex); } } } } }
注意jdk7的try-with-resource statement,inputstream和outputstream在try的开头声明,在try的结尾处自动close。
还有,将input和output都buffering!尤其对I/O-limited的网络程序,使用buffer的最坏结果是没有效果,最好结果是在性能上提高一个数量级。
class GZipAllFiles { public final static int THREAD_COUNT = 4; public static void main(String[] args) { ExecutorService pool = Executors.newFixedThreadPool(THREAD_COUNT); for (String filename : args) { File f = new File(filename); if (f.exists()) { if (f.isDirectory()) { File[] files = f.listFiles(); for (int i = 0; i < files.length; i++) { if (!files[i].isDirectory()) { // don't recurse directories Runnable task = new GZipRunnable(files[i]); pool.submit(task); } } } else { Runnable task = new GZipRunnable(f); pool.submit(task); } } } pool.shutdown(); }}
注意到pool.shutdown(),在你将所有task都添加到pool后就可以调用该方法,调用后并不会丢弃没有执行的task,只是告诉pool,没有新任务加入了,在执行完已有task后就可以shutdown了。
0 0
- c3 Threads - Thread Pools and Executors
- c3 Threads - Thread Scheduling
- c3 Threads - Returning Infomation From a Thread
- android in practice_Managing threads in thread pools(MyMovies project)
- c3 Threads - Running Threads
- Java 8 Concurrency Tutorial: Threads and Executors
- Thread Pools
- Thread Pools
- c3 Threads - Synchronization
- c3 Threads - Deadlock
- Java theory and practice: Thread pools and work queues
- Use Thread Pools Correctly: Keep Tasks Short and Nonblocking
- Why Threads and Basic Thread Management
- 线程池 Thread Pools
- Thread Pools 线程池
- 4 ways to do concurrency in Java: Threads, Executors, ForkJoin and Actors
- Java Thread Programming 1.9.1 - Threads and Swing
- Java Thread Programming 1.9.2 - Threads and Swing
- extjs4 treepanel左右键事件
- select, poll和epoll的区别
- This Android SDK requires Android Developer Toolkit version 22.6.2 or above
- 15个热门的编程趋势及15个逐步走向衰落的编程方向
- decide your linux OS is GUI or not
- c3 Threads - Thread Pools and Executors
- App天气预报
- Collections 的速度、空间及适用范围
- C++ sscanf()用法
- 跨站点脚本
- (1)创建用户定义的数据类型
- ajax跨域请求jsonp
- C语言中volatile关键字的作用
- UITableView创建