首页 > 编程知识 正文

安卓线程池面试题,多线程编程面试题

时间:2023-05-03 16:05:49 阅读:146667 作者:3608

1、新热的弊端

是否仍只有以下新线程执行异步任务?

你出局太多了。 新热的弊端如下。

每次新建thread时创建新对象的性能很差。

b .线程缺乏统一管理。 可能无限制地新建线程,可能会相互竞争,可能会过多地消耗系统资源,引起死机或oom。

c .缺乏定时执行、定期执行、线程中断等更多功能。

与new Thread相比,Java提供的四种类型的线程池的好处包括:

a .重用现有线程,减少创建和擦除对象的开销,性能良好。

b .根据项目大小有效控制最大并发线程数,提高系统资源利用率,同时避免资源过度竞争,避免堵塞。

c .提供定时执行、定期执行、单线程、并发数控制等功能。

2、Java线程池

Java通过执行程序提供了四种类型的线程池:

newCachedThreadPool创建一个可缓存的线程池。 如果线程池的长度超过需要处理的长度,请灵活地重用空闲线程,如果无法重用,请创建新线程。

newFixedThreadPool创建了一个固定长度的线程池,用于控制线程的最大并发行数,超出的线程将在队列中等待。

newScheduledThreadPool创建固定长度的线程池,以支持计划和定期任务执行。

newSingleThreadExecutor创建单线程池,只在唯一的工作线程上执行任务,以确保所有任务都按指定顺序(FIFO、LIFO、优先级)执行。

(1) newCachedThreadPool :

创建可缓存的线程池,如果线程池的长度超过处理所需的长度,则灵活回收可用线程;如果无法回收,则创建新线程。 示例代码如下:

线程池无限大,如果在执行第二个任务时完成了第一个任务,则执行第一个任务的线程将被复用,而不是每次创建新线程。

(2) newFixedThreadPool :

创建用于控制线程并发最大数量的固定长度线程池,超出的线程将在队列中等待。 示例代码如下:

线程池大小为3,每个任务输出索引,然后sleep 2是2秒,因此每2秒打印3个数字。

建议根据系统资源设置固定线程池的大小。 例如,Runtime.getRuntime ().availableProcessors )。 可以浏览PreloadDataCache。

(3) newScheduledThreadPool :

创建固定长度的线程池以支持计划和定期任务的执行。 延迟执行示例代码如下:

表示延迟3秒执行。

定期执行示例代码如下:

表示延迟1秒后每3秒执行一次。

方案设计比时间更安全、更强大

(4) newSingleThreadExecutor :

创建单线程线程池,以便只在唯一的工作线程上执行任务,并且所有任务都按指定的顺序(FIFO、LIFO、优先级)执行。 示例代码如下:

依次输出结果,相当于依次执行各个任务。

当前的GUI程序大部分是单线程的。 Android不适合同时执行单线程,例如数据库操作、文件操作、批量安装APP应用程序和批量删除APP应用程序,但可以用于可能影响IO堵塞性和UI线程响应的操作。

线程池角色:

线程池的作用是限制系统中运行的线程数。

根据系统环境情况,可以自动或手动设置线程数,以获得最佳运行结果; 减少了系统资源的浪费,越多系统就会变得拥挤,效率低下。 在线程池中控制线程数,其他线程排队等待。 一个任务执行完成后,从队列中取第一个任务开始执行。 如果队列中没有等待进程,则线程池中的此资源正在等待。 如果需要执行新任务,则可以在线程池中启动正在等待的工作线程,否则将进入队列。

为什么要使用线程池:

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

2 .根据系统的容错能力,可以调整线程池中的工作线线程的数量,以防止服务器因占用过多内存而疲惫不堪(每个线程需要约1MB的内存,线程越多,消耗的线程越多)

Java中线程池的顶部接口是Executor,但严格意义上说,Executor是运行线程的工具,而不是线程池。 真正的线程池接口是ExecutorService。

几个比较重要的类:

ExecutorService :真正的线程池接口。

scheduledexecutorservice :与timer/timertask一样,可以解决需要重复任务的问题。

thread pool executor :执行服务的默认实现。

scheduledthreadpoolexecutor :继承thread pool executor的ScheduledExecutorService接口实现、周期性任务调度的类实现。

配置线程池很复杂,尤其是在线程池原理不清楚的情况下,很可能会放置的线

程池不是较优的,因此在Executors类里面提供了一些静态工厂,生成一些常用的线程池。

1.newSingleThreadExecutor

创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

2.newFixedThreadPool

创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

3.newCachedThreadPool

创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,

那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。

4.newScheduledThreadPool

创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。

实例代码

一、固定大小的线程池,newFixedThreadPool:

输出结果:

改变ExecutorService pool = Executors.newFixedThreadPool(5)中的参数:ExecutorService pool = Executors.newFixedThreadPool(2),输出结果是:

从以上结果可以看出,newFixedThreadPool的参数指定了可以运行的线程的最大数目,超过这个数目的线程加进去以后,不会运行。其次,加入线程池的线程属于托管状态,线程的运行不受加入顺序的影响。

二、单任务线程池,newSingleThreadExecutor:

仅仅是把上述代码中的ExecutorService pool = Executors.newFixedThreadPool(2)改为ExecutorService pool = Executors.newSingleThreadExecutor();

输出结果:

可以看出,每次调用execute方法,其实最后都是调用了thread-1的run方法。

三、可变尺寸的线程池,newCachedThreadPool:

与上面的类似,只是改动下pool的创建方式:ExecutorService pool = Executors.newCachedThreadPool();

输出结果:

这种方式的特点是:可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。

四、延迟连接池,newScheduledThreadPool:

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。