前面文章用直接使用Thread类的start方法来新启动一个线程,看起来貌似没有什么问题,问题就在于线程使用场景的需求上,如果希望每个一段时间自动运行一次这个线程,如果想使用线程池,这个Start方法就完全不够了。
下面我们来看看Java并发包中的Executor接口吧

  1. public interface java.util.concurrent.Executor {
  2. public void execute(java.lang.Runnable arg0);
  3. }

实际上是把调度线程的功能抽象出来,java 5.0内建了不少Executor的实现,当然你自己也可以去实现这个接口:
在当前线程中启动一个功能

  1. import java.util.concurrent.Executor;
  2. public class myExecutor implements Executor {
  3. @Override
  4. public void execute(Runnable arg0) {
  5. arg0.run();
  6. }
  7. }

在新线程中其中一个功能

  1. import java.util.concurrent.Executor;
  2. public class myExecutor implements Executor {
  3. @Override
  4. public void execute(Runnable arg0) {
  5. new Thread(arg0).start();
  6. }
  7. }

以上两个例子让您明白,你可以实现你需要的线程启动模型!
对于内建的Executor,其实也基本够用了:
单线程:顾名思义就是一个线程,和Thread也没有什么太大区别

  1. Executor oneThread = Executors.newSingleThreadExecutor();

固定线程数的池:固定数量的线程,但是加入了池的能力,在一个线程完成任务后不会释放其在内存中位置,而是“缓存”起来,一旦一个新的任务到来就会“重用”这个线程的空间。但是其数量是受到限制的,一旦超过,也不会出现什么异常,只是等待时间会变得长一些,就是感觉慢一些罢了。

  1. Executor fixedPool = Executors.newFixedThreadPool(10);

无限数量的线程池:很好的线程池,除了和FixedThreadPool有着相同的能力,但是线程数却使无限的,也就是说每加入一个线程就会池化,但是无限的对内存的有限,显然是悖论,所以
加得越多,重用机会也减少了,内存占有越来越大,不是很好的方式了。最好是根据需要来使用FixedThreadPool和CachedThreadPool!

  1. Executor unboundedPool = Executors.newCachedThreadPool();

另外你还看到我们在使用这些内建的Executor时,发现都是Executors这个类负责的,不要大惊小怪,不过就是一个工厂类,提供一些静态工厂方法来便利地帮助你创建这些Executor实例而已。

实际上,Executor接口只是这些内建的Executor的根,它们其实是直接实现了ExecutorService接口,而ExectorService和Executor接口的关系是:

  1. public interface java.util.concurrent.ExecutorService extends java.util.concurrent.Executor {
  2. public void shutdown();
  3. public java.util.List shutdownNow();
  4. public boolean isShutdown();
  5. public boolean isTerminated();
  6. public boolean awaitTermination(long arg0, java.util.concurrent.TimeUnit arg1) throws java.lang.InterruptedException;
  7. public java.util.concurrent.Future submit(java.util.concurrent.Callable arg0);
  8. public java.util.concurrent.Future submit(java.lang.Runnable arg0, java.lang.Object arg1);
  9. public java.util.concurrent.Future submit(java.lang.Runnable arg0);
  10. public  java.util.List invokeAll(java.util.Collection arg0) throws java.lang.InterruptedException;
  11. public java.util.List invokeAll(java.util.Collection arg0, long arg1, java.util.concurrent.TimeUnit arg2) throws java.lang.InterruptedException;
  12. public java.lang.Object invokeAny(java.util.Collection arg0) throws java.lang.InterruptedException, java.util.concurrent.ExecutionException;
  13. public java.lang.Object invokeAny(java.util.Collection arg0, long arg1, java.util.concurrent.TimeUnit arg2) throws java.lang.InterruptedException, java.util.concurrent.ExecutionException, java.util.concurrent.TimeoutException;

一看就看明白了,这个接口头拓展于Executor,并且内建的Executor大多从ExecutorService实现的,在Executor的基础上,第一加入了生命周期控制方法,如shutdown,第二加入了对Future的支持(在上一讲已经有Future的例子了,下面还有一个),那么如果打个比方,Thread类自行车发条,Executor是摩托车发动机,ExecutorService就是一个跑车发动机.

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.Random;
  4. import java.util.concurrent.*;
  5. import java.util.concurrent.atomic.AtomicInteger;
  6. public class FutureTaskTest {
  7. private static AtomicInteger Count = new AtomicInteger(0)
  8. @SuppressWarnings("unchecked")
  9. public static void main(String args[]) {
  10. ExecutorService es = Executors.newFixedThreadPool(10);
  11. List<Future<Integer>> tasks = new ArrayList<Future<Integer>>();
  12. for (int i = 0; i <= 10; i++) {
  13. FutureTask<Integer> futureTask = new FutureTask<Integer>(
  14. new Callable() {
  15. @SuppressWarnings("static-access")
  16. public Integer call() throws Exception {
  17. Thread.currentThread().sleep(
  18. (new Random()).nextInt(1000));
  19. return Count.getAndIncrement();
  20. }
  21. });
  22. tasks.add(futureTask);
  23. es.submit(futureTask);
  24. }
  25. Integer result = new Integer(0);
  26. try {
  27. for (Future<Integer> task : tasks) {
  28. result += (Integer) task.get();
  29. }
  30. es.shutdown();
  31. System.out.println(result);
  32. } catch (InterruptedException e) {
  33. e.printStackTrace();
  34. } catch (ExecutionException e) {
  35. e.printStackTrace();
  36. }
  37. }
  38. }

那么除了上面提高的内建类,还有什么吗?
ScheduledExecutorService 
一看名字就猜出来了,它可以Schedule去执行线程!也就是指定一个时间、间隔去执行线程中的任务.

以上都是用来调度线程每隔一个时间间隔执行的方法,不仅有Runnable的,还有Callable的。

经常能用到的东西就这些,下一讲是有关线程锁的话题.

有关Java 5.0+ 并发包的探讨-2 section的更多相关文章

  1. Java多线程--JDK并发包(2)

    Java多线程--JDK并发包(2) 线程池 在使用线程池后,创建线程变成了从线程池里获得空闲线程,关闭线程变成了将线程归坏给线程池. JDK有一套Executor框架,大概包括Executor.Ex ...

  2. Java多线程--JDK并发包(1)

    Java多线程--JDK并发包(1) 之前介绍了synchronized关键字,它决定了额一个线程是否可以进入临界区:还有Object类的wait()和notify()方法,起到线程等待和唤醒作用.s ...

  3. 【JAVA各版本特性】JAVA 1.0 - JAVA 12

    make JDK Version 1.01996-01-23 Oak(橡树) 初代版本,伟大的一个里程碑,但是是纯解释运行,使用外挂JIT,性能比较差,运行速度慢. JDK Version 1.119 ...

  4. WebDriver基本API使用(基于Java)V1.0

    WebDriver基本API使用(基于Java)V1.0http://www.docin.com/p-803032877.html

  5. 出现错误:Unable to load configuration. - action - file:/E:/Java/Tomcat7.0/apache-tomcat-7.0.68-windows-x64/apache-tomcat-7.0.68/webapps/SSH2Integrate/WEB-INF/classes/struts.xml:8:43

    严重: Exception starting filter struts2 Unable to load configuration. - action - file:/E:/Java/Tomcat7 ...

  6. 用 for/in 在 Java 5.0 中增强循环

    这个方便的构造提供了什么?什么时候适用于代码? Brett McLaughlin (brett@newInstance.com), 作者/编辑, O'Reilly Media, Inc. 简介: fo ...

  7. 用java从0生成一个简单的excel

    用java从0生成一个简单的excel 目标 用代码实现对一个excel的基础操作,包括创建,插入文字,(好像就这些了),生成的excel可以用wps打开,如果直接用c++的文件流会生成假的xls表格 ...

  8. java10.0.2和java 11.0.1配置环境变量

    java10.0.2 在网上找了各种方法一直也没配好打开jak下的lib文件夹发现并没有tools.jar,后经查询jdk-9后就没有了上述.jar文件所以我的配置方法如下 ClASSPATH C:\ ...

  9. Java并发:多线程和java.util.concurrent并发包总结

    多线程和java.util.concurrent并发包 转载:

随机推荐

  1. (九十六)借助APNS实现远程通知、后台任务

    APNS全称为Apple Push Notification Service,可以实现在app不启动时也能通过服务器推送到iOS端特定设备的功能. APNS的实现原理为先发送设备的UDID和应用的Bu ...

  2. StringBuffer与StringBuilder详解

    刚刚在参加网易实习生在线考试的时候,出了一道选择题谈到了StringBuilder这个类的一些选项,虽然那道题自己做对了,但是也提醒了我应该好好了解一些StringBuffer与StringBuild ...

  3. DB 查询分析器 6.04 在 Windows 10 上的安装与运行展示

    DB查询分析器 6.04 在 Windows 10 上的安装与运行展示 中国本土程序员马根峰(CSDN专访马根峰:海量数据处理与分析大师的中国本土程序员 http://www.csdn.net/art ...

  4. Android进阶(九)APP编程感想

    从初识Android到现在,在不断做APP(二维码.条形码扫描,彩票购买,火车票余票查询)的过程中,自己学会了很多东西.找时间整理了一下,总结如下: 其中,对于前两个APP,自己都是在他人已完成的基础 ...

  5. 将Ext JS 6应用程序导入Web项目

    由于Ext JS 6包含了Sencha Touch,因而在应用程序结构有了些改变,Ext JS 5的方法已经不适用于新版本了.经过研究,发现6导入Web项目要比5简单. 下面来说说导入的过程. 使用S ...

  6. Linux C 下的大文件操作

    这里说的大文件指大小超过4G的文件. 在32位环境下,linux默认打开.读.写超过4G的文件会返回错误.定义如下宏可以突破这个限制,对read/write和fread/fwrite同时有效. 注意它 ...

  7. 【UI 设计】PhotoShop基础工具 -- 移动工具

    还是学点美工的东西吧, 业余爱好   比学编程还难 PS版本 : PhotoShop CS6 1. 移动工具 (1) 工具栏和属性栏 工具栏 和 属性栏 : 左侧的是工具栏, 每选中一个工具, 在菜单 ...

  8. (NO.00002)iOS游戏精灵战争雏形(六)

    接下来我们给MainScene场景再添加一个精灵,作为敌人. 双击SpriteBuilder中的MainScene.ccb,从控件库拖入一个CCSprite到CCPhysicsNode中,设置精灵帧为 ...

  9. leetcode 169 Majority Element 冰山查询

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  10. (NO.00001)iOS游戏SpeedBoy Lite成形记(六)

    为了能让玩家可以在比赛结束时清楚看到每位选手的成绩,我们需要在GameScene场景的track对象中添加一些新的元素. 在SpriteBuilder中打开GameScene.ccb,创建1个标签对象 ...