线程池简单例子

文案摘自:《Java 编程思想》
FixedThreadPool
使用了有限的线程集来执行所提交的任务。还提供了一种重要的并发保证,其他线程不会(即没有两个线程会)被并发调用。这会改变任务的加锁需求。(超过限定的线程会排队等待,在已运行的线程结束后,开始执行)

CachedThreadPool
在程序执行过程中通常会创建与所需数量相同的线程,然后在它回收旧线程时停止创建新线程

SingleThreadExecutor
就像是线程数量为1的FixedThreadPool。这对于你希望再另一个线程中连续运行的任何事物(长期存活的任务)来说,都是很有用的,例如监听进入的套接字连接的任务。它对于希望在线程中运行的短任务也同样很方便,例如,更新本地或远程日志的小任务,或者是事件分发线程。
如果向SingleThreadEcecutor提交了多个任务,那么这些任务将排队,每个任务都会在下一个任务开始之前运行结束,所有的任务将使用相同的线程。因此,SingleThreadExecutor会序列化所有提交给它的任务,并会维护它自己(隐藏)的悬挂任务队列。

下面是自己写的对应的简单例子
好,下面开始贴代码,然后大概说两句

IntelliJ IDEA 新建工程:ExecutorDemo

新建类:ExecutorFactory,代码如下

public class ExecutorFactory {

    public static ExecutorService create(String type) {
        ExecutorService service = null;
        switch (type) {
            case "cache":
                service = Executors.newCachedThreadPool();
                break;
            case "fixed"://注意:这里创建的线程池限定最大是2
                service = Executors.newFixedThreadPool(2);
                break;
            case "single":
                service = Executors.newSingleThreadExecutor();
                break;
        }
        return service;
    }
}

新建类:ExecutorDemo,代码如下

public class ExecutorDemo {

    private ExecutorService service;

    public ExecutorDemo(String type) {
        service = ExecutorFactory.create(type);
    }

    public Future<?> submit(RunnableClass runnable) {
        return service.submit(runnable);
    }

    public void execute(RunnableClass runnable) {
        service.execute(runnable);
    }

    public void release() {
        service.shutdown();
    }

}

新建类:RunnableClass,代码如下

public class RunnableClass implements Runnable {

    private static int taskCount = 0;
    private final int id = taskCount++;

    @Override
    public void run() {
        System.out.println("id:" + id + "开始");
        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("id:" + id + ",完成");
    }
}

新建类:ExecutorMainTest,代码如下

public class ExecutorMainTest{

    public static void main(String[] args) {
        DemoTest test = new DemoTest();

//        test.test("cache");
//        test.test("fixed");
//        test.test("single");
    }

    public void test(String type) {
        ExecutorDemo demo = new ExecutorDemo(type);
        for (int i = 0; i < 5; i++) {
            demo.execute(new RunnableClass());
        }
        demo.release();
    }
}

下面为ExecutorMainTest中,不同的testType的测试结果:

test.test(“cache”)的结果是

id:1开始
id:0开始
id:2开始
id:3开始
id:4开始
id:0,完成
id:1,完成
id:2,完成
id:4,完成
id:3,完成

因为CachedThreadPool会创建与所需数量相同的线程,所以看到的结果是,连续创建了足够的线程后,然后输出结果

下面是test.test(“fixed”)的输出结果

id:0开始
id:1开始
id:0,完成
id:1,完成
id:2开始
id:3开始
id:3,完成
id:2,完成
id:4开始
id:4,完成

因为在ExecutorFactory中创建FixedThreadPool时,限定了最大的线程数是2,所以看到的结果是:先创建两个线程,然后等这两个线程执行完成后,在复用这两个线程执行新的任务,等执行完毕后再复用,直到任务结束。

下面是test.test(“single”)的执行输出结果

id:0开始
id:0,完成
id:1开始
id:1,完成
id:2开始
id:2,完成
id:3开始
id:3,完成
id:4开始
id:4,完成

因为SingleThreadExecutor中只有一个线程在运行,所以看到的结果是,创建一个线程执行完成,再复用,进行下一个任务,直到结束。

execute和submit方法的区别是:
1、接收的参数不一样
2、submit有返回值,而execute没有
3、submit方便Exception处理
具体可参考:ExecutorService的execute和submit方法

好了,大概先说这么多
代码地址:
https://github.com/b1234569856/JavaDemo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值