对Java线程池的理解

1. Runnable是线程吗?

Runnable不是线程,Thread才是。比如单一线程池Executor会在内部创建一个Thread,这个Thread会从一个任务队列中取出用户提交的任务并执行,如果在执行的过程中出现异常,Executor会自动启动新线程继续执行

 

2. Thread的优缺点?

优点:通过new Thread()创建线程API简单易于使用,结构清晰,对于执行单一的一次性任务十分便利。

缺点:1. 每次new Thread新建对象性能差

           2. 没有线程管理者,可能会无限制新建线程,互相之间竞争,极有可能占用过多的系统资源导致OOM

           3. 缺乏更多功能,比如定时、定期、并发数控制等功能

 

3. Thread和Executor的区别?

(打个比方:为什么刀要分为很多种,比如菜刀、西瓜刀、杀猪刀? >> 是功能不同,需要针对性处理)。

两者最大的区别应该是Executor更像是一个管理者和Thread的集合,而Thread只是一个任务的执行者,Thread处理的事物目的明确、逻辑简单。

 

4. 线程池的优点?

1. 缓存线程,进行池化,可实现对线程的重复利用,避免重复创建和销毁线程所带来的性能开销。

2. 当任务在执行的过程中如出现异常,会重新创建线程继续完成任务。

3. 任务按照指定的规则执行,线程池通过队列的形式来接收任务,通过空闲线程来逐一取出任务调度。

4. 可定制拒绝策略,即任务队列已满时,后来的任务可拒绝处理。

 

5.线程池的基本使用方法

public class TestExecutor
{
    public static void main(String[] args)
    {
//        testCachedThreadPool();
//        testFixedThreadPool();
//        testSingleThreadExecutor();
//        testScheduledThreadPool();
        testSingleThreadScheduledExecutor();
    }

    /**
     * 可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.
     */
    static void testCachedThreadPool()
    {
        ExecutorService es = Executors.newCachedThreadPool();
        for(int i = 0 ; i < 10 ; i++){
            final int index = i;
            es.execute(new Runnable() {
                
                @Override
                public void run()
                {
                    System.out.println("index = " + index);
                }
            });
        }
    }
    
    /**
     * 定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
     */
    static void testFixedThreadPool()
    {
        ExecutorService es = Executors.newFixedThreadPool(3);
        for(int i = 0 ; i < 10 ; i++){
            final int index = i;
            es.execute(new Runnable() {
                
                @Override
                public void run()
                {
                    System.out.println("index = " + index);
                    try
                    {
                        Thread.sleep(2000);
                    } catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
    
    /**
     * 一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
     */
    static void testSingleThreadExecutor()
    {
        ExecutorService es = Executors.newSingleThreadExecutor();
        for(int i=0;i<10;i++){
            final int index = i;
            es.execute(new Runnable() {
                
                @Override
                public void run()
                {
                    System.out.println("index = "+index);
                    try
                    {
                        Thread.sleep(2000);
                    } catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
    
    /**
     * 定长线程池,支持定时及周期性任务执行
     */
    static void testScheduledThreadPool()
    {
        ScheduledExecutorService ses = Executors.newScheduledThreadPool(3);
        
        //延迟3秒钟
        ses.schedule(new Runnable() {
            
            @Override
            public void run()
            {
                System.out.println("delay 3s");
            }
        }, 3, TimeUnit.SECONDS);
        
        //延迟3秒钟,以固定频率5s定时执行
        ses.scheduleAtFixedRate(new Runnable() {
            
            @Override
            public void run()
            {
                System.out.println("run ...");                
            }
        }, 3, 5, TimeUnit.SECONDS);
    }

    /**
     * 单线程化的线程池,支持定时及周期性任务执行
     * 适用于非批量操作,如app的安装、卸载等
     */
    static void testSingleThreadScheduledExecutor()
    {
        ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
        
        //延迟3秒钟
        ses.schedule(new Runnable() {
            
            @Override
            public void run()
            {
                System.out.println("delay 3s");
            }
        }, 3, TimeUnit.SECONDS);
        
        
        //延迟3秒钟,以固定频率5s定时执行
        ses.scheduleAtFixedRate(new Runnable() {
            
            @Override
            public void run()
            {
                System.out.println("run ... ");
            }
        }, 3, 5, TimeUnit.SECONDS);
    }
    
}

 

转载于:https://my.oschina.net/wangyujue1991/blog/680694

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答:Java线程池Java中的一个重点知识,并且在Java的工作中经常会遇到,因此在面试中也是必问的面试题目。以下是一些常见的Java线程池面试题: 1. 谈谈什么是线程池? 2. 为什么要使用线程池? 3. 你们哪些地方会使用到线程池? 4. 线程池有哪些作用? 5. 线程池的创建方式有哪些? 6. 线程池底层是如何实现复用的? 7. ThreadPoolExecutor核心参数有哪些? 8. 线程池创建的线程会一直在运行状态吗? 9. 为什么阿里巴巴不建议使用Executors? 10. 线程池的底层实现原理是什么? 11. 线程池队列满了,任务会丢失吗? 12. 线程池的拒绝策略类型有哪些? 13. 线程池如何合理配置参数? 这些问题涵盖了线程池的基本概念、使用场景、实现原理以及相关的配置和策略等方面的知识。了解这些问题能够帮助面试者更好地理解和应用Java线程池。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [java线程池面试题有哪些?java线程池常见面试题](https://blog.csdn.net/muli525/article/details/123553744)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [(一)【Java精选面试题】线程池底层实现原理(含答案)](https://blog.csdn.net/qq_30999361/article/details/124924343)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值