- 浏览: 637249 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
luo_ganlin:
别的不多说,点个赞!
关于Android隐式启动Activity -
IWSo:
谢楼主!研究了好久,原来是这样!
android中如何让LinearLayout实现点击时背景图片切换 -
fantao005x:
粘帖的不错
android中如何让listview的内容全部显示出来 -
learner576539763:
Android_gqs 写道请问博主,Viewstub 可实现 ...
android中ViewStub使用 -
goontosoon:
抄的什么啊,狗屁不通
对ContentProvider中getType(Uri uri)
从 Java 5 开始,Java 提供了自己的线程池。线程池就是一个线程的容器,每次只执行额定数量的线程。 java.util.concurrent.ThreadPoolExecutor 就是这样的线程池。它很灵活,但使用起来也比较复杂,本文就对其做一个介绍。
首先是构造函数。以最简单的构造函数为例:
public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue)
看起来挺复杂的。这里介绍一下。
corePoolSize 指的是保留的线程池大小。
maximumPoolSize 指的是线程池的最大大小。
keepAliveTime 指的是空闲线程结束的超时时间。
unit 是一个枚举,表示 keepAliveTime 的单位。
workQueue 表示存放任务的队列。
我们可以从线程池的工作过程中了解这些参数的意义。线程池的工作过程如下:
1、线程池刚创建时,里面没有一个线程。任务队列是作为参数传进来的。不过,就算队列里面有任务,线程池也不会马上执行它们。
2、当调用 execute() 方法添加一个任务时,线程池会做如下判断:
a. 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;
b. 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列。
c. 如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还是要创建线程运行这个任务;
d. 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会抛出异常,告诉调用者“我不能再接受任务了”。
3、当一个线程完成任务时,它会从队列中取下一个任务来执行。
4、当一个线程无事可做,超过一定的时间(keepAliveTime)时,线程池会判断,如果当前运行的线程数大于 corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩到 corePoolSize 的大小。
这样的过程说明,并不是先加入任务就一定会先执行。假设队列大小为 10,corePoolSize 为 3,maximumPoolSize 为 6,那么当加入 20 个任务时,执行的顺序就是这样的:首先执行任务 1、2、3,然后任务 4~13 被放入队列。这时候队列满了,任务 14、15、16 会被马上执行,而任务 17~20 则会抛出异常。最终顺序是:1、2、3、14、15、16、4、5、6、7、8、9、10、11、12、13。下面是一个线程池使用的例子:
public static void main(String[] args) { BlockingQueue queue = new LinkedBlockingQueue(); ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.DAYS, queue); for (int i = 0; i < 20; i++) { executor.execute(new Runnable() { public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(String.format("thread %d finished", this.hashCode())); } }); } executor.shutdown(); }
对这个例子的说明如下:
1、BlockingQueue 只是一个接口,常用的实现类有 LinkedBlockingQueue 和 ArrayBlockingQueue。用 LinkedBlockingQueue 的好处在于没有大小限制。这样的话,因为队列不会满,所以 execute() 不会抛出异常,而线程池中运行的线程数也永远不会超过 corePoolSize 个,keepAliveTime 参数也就没有意义了。
2、shutdown() 方法不会阻塞。调用 shutdown() 方法之后,主线程就马上结束了,而线程池会继续运行直到所有任务执行完才会停止。如果不调用 shutdown() 方法,那么线程池会一直保持下去,以便随时添加新的任务。
到这里对于这个线程池还只是介绍了一小部分。ThreadPoolExecutor 具有很强的可扩展性,不过扩展它的前提是要熟悉它的工作方式。
java.util.concurrent.ThreadPoolExecutor 类提供了丰富的可扩展性。你可以通过创建它的子类来自定义它的行为。例如,我希望当每个任务结束之后打印一条消息,但我又无法修改任务对象,那么我可以这样写:
ThreadPoolExecutor executor = new ThreadPoolExecutor(size, maxSize, 1, TimeUnit.DAYS, queue) {
@Override
protected void afterExecute(Runnable r, Throwable t) {
System.out.println("Task finished.");
}
};
除了 afterExecute 方法之外,ThreadPoolExecutor 类还有 beforeExecute() 和 terminated() 方法可以重写,分别是在任务执行之前和整个线程池停止之后执行。
除了可以添加任务执行前后的动作之外, ThreadPoolExecutor 还允许你自定义当添加任务失败后的执行策略。你可以调用线程池的 setRejectedExecutionHandler() 方法,用自定义的 RejectedExecutionHandler 对象替换现有的策略。 ThreadPoolExecutor 提供 4 个现有的策略,分别是:
ThreadPoolExecutor.AbortPolicy:表示拒绝任务并抛出异常
ThreadPoolExecutor.DiscardPolicy:表示拒绝任务但不做任何动作
ThreadPoolExecutor.CallerRunsPolicy:表示拒绝任务,并在调用者的线程中直接执行该任务
ThreadPoolExecutor.DiscardOldestPolicy:表示先丢弃任务队列中的第一个任务,然后把这个任务加进队列。
这里是一个例子:
ThreadPoolExecutor executor = new ThreadPoolExecutor(size, maxSize, 1, TimeUnit.DAYS, queue); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
除此之外,你也可以通过实现 RejectedExecutionHandler 接口来编写自己的策略。下面是一个例子:
ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.SECONDS, queue, new RejectedExecutionHandler() { public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { System.out.println(String.format("Task %d rejected.", r.hashCode())); } } );
发表评论
-
EditText软键盘弹出问题解决
2013-02-26 23:10 1468当带有EditView的activity第一次进入时,第一 ... -
android中获取系统相关属性adb
2012-11-15 14:41 22011.查看系统相关属性可以通过: adb shell ... -
Android使用Intent传递复杂参数及复杂参数列表
2012-11-05 17:29 1637刚开始一直纠结于Intent只能put像int, ... -
解决P6200/P6800扩展卡第三方软件不可写的BUG
2012-11-05 17:01 1035从XDA看来的步骤:1. Using a root-e ... -
android 中跟actionbar相关的属性
2012-10-25 17:07 2485android:uiOptions 这个属性用于设置A ... -
source insight使用快捷键
2012-10-25 10:59 1560F5指定行号,实现行跳转,在遇到编译错误的时候,能特 ... -
android中推出应用比较有效率的方法
2012-10-11 16:57 1167添加一个全局变量作为程序退出的标记(boolean类型) ... -
declare-styleable的使用
2012-10-09 13:59 1179declare-styleable的使用 decl ... -
android程序安全的建议
2012-09-29 14:58 5310如果保证自己的 ... -
android应用检测更新代码
2012-09-24 17:40 1850JAVA代码: UpdateManager.java ... -
adb命令详解
2012-09-19 15:04 2891Android adb的常用命令略解 Androi ... -
android中屏蔽其它系统按钮的dialog
2012-09-18 10:13 1653public class MyProgress ... -
如何给Scrollview里内容截屏并生成bitmap,注意:Scrollview里面内容较多有滚动了
2012-09-18 10:07 1647使用for循环递归累加其内部的子控件的高度: p ... -
wakelock的使用
2012-09-17 11:44 10086PowerManager.WakerLock是我分析St ... -
启动另外一个apk
2012-09-14 13:16 905这篇博文主要是获取其他apk程序的启动的主intent, ... -
android中全屏的方法
2012-09-14 13:04 9691.直接代码编写 @Override ... -
android:installLocation简析
2012-09-12 15:25 1122在Froyo(android 2.2,API Le ... -
外部apk启动启动另外一个apk
2012-09-06 17:54 1053public class TestingBroadc ... -
listview如何实现圆角
2012-09-05 17:32 1939首先呢,我们还是看几个示图:(这是360推出的一款天气预 ... -
android中如何更有效率得解析xml
2012-09-05 17:17 1328好久没写过博文了,最近在做xml方面的解析,x ...
相关推荐
总结,这个"Java/Android线程池演示Demo"旨在通过实例展示如何在Android和Java项目中使用线程池进行并发处理,帮助开发者理解线程池的工作原理和优势,以及如何根据应用需求配置和管理线程池。通过分析和实践这个...
jdk自带线程池实例详解 jdk自带的线程池是Java开发中一个非常重要的概念,特别是在多线程编程中。线程池是线程的容器,每次只执行额定数量的线程,线程池就是用来管理这些额定数量的线程。下面我们来详细了解jdk...
Java线程池是一种高效利用系统资源的机制,它允许开发者预先配置一定数量的线程,以便在...通过对JDK自带的`ThreadPoolExecutor`源码的学习,我们可以更深入地了解线程池的工作细节,以便更好地利用这一强大的工具。
- 线程池:ExecutorService和ThreadPoolExecutor的理解和应用,以及线程池的配置和优化。 5. 输入/输出流: - 文件操作:如何进行文件的读写,包括File类的使用和FileInputStream/FileOutputStream等流的使用。 ...
- 动态代理的实现,如Java自带的InvocationHandler接口。 10. **JVM** - 类加载机制,双亲委派模型的理解。 - 方法区与运行时常量池,理解新生代、老年代和永久代的内存划分。 - 垃圾收集器的选择与调优策略。 ...
最后,工具在Java多线程开发中也起着重要作用,例如JVisualVM、JConsole等Java自带的监控工具,可以帮助开发者分析线程状态、检测死锁、查看内存使用情况等,从而更好地理解和优化多线程程序。 总之,Java多线程...
类加载器分为引导类加载器、扩展类加载器和应用类加载器。 3. **字节码执行**:JVM通过解释器和即时编译器(如HotSpot的C1和C2编译器)将字节码转换为机器码执行。 二、内存管理 1. **堆内存**:存储对象实例,...
7. **线程与锁优化**:理解线程池的配置(如ThreadPoolExecutor的corePoolSize, maximumPoolSize, keepAliveTime等参数),死锁的检测和避免,以及锁的升级过程(从偏向锁到轻量级锁再到重量级锁)。 8. **编译优化...
Java的`ExecutorService`和`ThreadPoolExecutor`允许创建线程池,有效管理线程资源,避免频繁创建和销毁线程的开销。线程池可以通过`Executors`工厂类的静态方法创建,如`Executors.newFixedThreadPool(int ...
尽管Java自带了`java.util.concurrent`包下的ThreadPoolExecutor,但easy-threadpool针对特定场景提供了更简洁的API和更灵活的定制选项,适合对线程池有特定需求的开发者使用。 三、easy-threadpool核心组件 1. ...
这个名为“JVM_JUC_Demo”的实践案例旨在帮助开发者深入理解和应用这两个关键领域的知识。 首先,我们来探讨JVM。JVM是Java语言的核心组成部分,它负责将字节码转换为机器码,执行Java程序。理解JVM的工作原理对于...
- 自带线程池管理,避免过度创建线程。 缺点: - 不适用于长时间运行的任务,可能导致应用无响应(ANR)。 - 内部线程池大小有限,大量并发使用可能导致性能下降。 - 不利于代码复用,因为每个AsyncTask实例通常...