美文网首页androidJava 杂谈
Java线程和线程池的对比

Java线程和线程池的对比

作者: 风暴小狼 | 来源:发表于2019-05-20 16:38 被阅读52次

Runnable是线程吗?

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

Thread的优缺点?

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

缺点:

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

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

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

线程池的优点? 

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

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

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

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

Thread和Executor的区别?

(为什么刀要分为很多种,比如菜刀、砍刀、杀猪刀?答案是功能不同,需要针对性处理)。

两者最大的区别应该是Executor更像是一个管理者和Thread的集合,而Thread只是一个任务的执行者。

Executor线程池的使用

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);

    }

}

相关文章

网友评论

    本文标题:Java线程和线程池的对比

    本文链接:https://www.haomeiwen.com/subject/dcdkzqtx.html