对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

你可能感兴趣的:(java)