A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 吴硕 中级黑马   /  2012-10-15 20:40  /  1951 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 吴硕 于 2012-10-15 20:45 编辑

从JDK1.5开始,Java内建支持线程池,张老师的项目里用到了线程池,分享出来一点线程池知识

系统启动一个新线程的成本是比较高的,因为它涉及与操作系统交互
在这种情况下,使用线程池可以很好的提高性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池

线程池可以有效的控制系统中并发线程的数量,
系统中包含大量并发线程时,会导致系统性能剧烈下降,甚至导致JVM崩溃
而线程池的最大线程数参数可以控制系统中并发线程数目不超过此数目
Java提供了一个Executors工厂类来产生线程池

以下三个静态工厂方法返回ExecutorService对象,该对象代表一个线程池,它可以执行Runnable对象
或Callable对象所代表的线程
newCachedThreadPool()
    具有缓存功能的线程池,系统根据需要创建线程,这些线程将会被缓存在线程池中
newFixedThreadPool(int nThreads)
    创建一个可重用的、具有固定线程数的线程池
newSingleThreadExecutor()
    创建一个只有单线程的线程池,它相当于newFixedThreadPool方法时传入参数1

以下两个方法返回一个ScheduledExecutorService线程池,它是ExecutorService的子类,

它可以在指定延迟后执行线程任务
newScheduledThreadPool(int corePoolSize)
    创建具有指定线程数的线程池,它可以在指定延迟后执行线程任务
    corePoolSize指池中所保存的线程数,即使线程是空闲的也被保存在线程池内
newSingleThreadScheuledExecutor()
    创建只有一条线程的线程池,它可以在指定延迟后执行线程任务

ExecutorService里提供了如下三个方法:
Future<?> submit(Runnable task)
    将一个Runnable对象提交给指定的线程池,线程池将在有空闲线程时执行Runnable对象代表的任务
    其中Future对象代表Runnable任务的返回值,但run方法没有返回值,所以Future对象
    将在run方法执行结束后返回null。
    但可以调用Future的isDone()、isCancelled()方法来获得Runnable的执行状态。
<T> Future<T> submit(Runnable task, T result)
    result显示指定线程执行结束后的返回值,所以Future对象将在run方法执行结束后返回result
<T> Future<T> submit(Callable<T> task)
    将一个Callable对象提交给指定的线程池,Future代表Callable对象里call方法的返回值
   
ScheduledExecutorService代表可在指定延迟或周期性执行线程任务的线程池,它提供了如下四个方法:
ScheduledFuture<V> schedule(Callable<V> Callable, long delay, TimeUnit unit)
    指定callable任务将在delay延迟后执行
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)
    指定command任务将在delay延迟后执行
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
    指定command任务将在delay延迟后执行,而且以设定频率重复执行。
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
    创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和
    下一次执行开始之间都存在给定的延迟
   
当用完一个线程池后,应该调用该线程池的shutdown()方法,该方法将启动线程池的关闭序列

一个例子:
  1. import java.util.concurrent.ExecutorService;
  2. import java.util.concurrent.Executors;

  3. /**
  4. * 线程池
  5. *
  6. */
  7. public class ThreadPoolTest
  8. {

  9.         /**
  10.          * @param args
  11.          */
  12.         public static void main(String[] args)
  13.         {
  14.                 //创建一个具有固定线程数(6)的线程池
  15.                 ExecutorService pool = Executors.newFixedThreadPool(6);
  16.                 //向线程池中提交两个线程
  17.                 pool.submit(new ThreadTest());
  18.                 pool.submit(new ThreadTest());
  19.                 //关闭线程池
  20.                 pool.shutdown();

  21.         }

  22. }

  23. class ThreadTest implements Runnable
  24. {
  25.         public void run()
  26.         {
  27.                 for(int i = 0; i < 100; i++)
  28.                 {
  29.                         System.out.println(Thread.currentThread().getName()+"--"+"i的值为"+i);
  30.                 }
  31.         }
  32. }


  33. 我的输出结果:
  34. pool-1-thread-1--i的值为0
  35. pool-1-thread-2--i的值为0
  36. pool-1-thread-1--i的值为1
  37. pool-1-thread-2--i的值为1
  38. pool-1-thread-1--i的值为2
  39. pool-1-thread-2--i的值为2
  40. pool-1-thread-1--i的值为3
  41. pool-1-thread-2--i的值为3
  42. pool-1-thread-1--i的值为4
  43. pool-1-thread-2--i的值为4
  44. pool-1-thread-1--i的值为5

复制代码

1 个回复

倒序浏览
好东西,存起来看看
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马