【十八掌●基本功篇】第一掌:Java之多线程--3-线程池

这一篇博文是【大数据技术●降龙十八掌】系列文章的其中一篇,点击查看目录:这里写图片描述大数据技术●降龙十八掌


系列文章:
【十八掌●基本功篇】第一掌:Java之IO
【十八掌●基本功篇】第一掌:Java之多线程–1-一些概念
【十八掌●基本功篇】第一掌:Java之多线程–2-join、同步、死锁、等待
【十八掌●基本功篇】第一掌:Java之多线程–3-线程池

线程池的基本思想是开辟一块内存空间,里面存放了很多的线程,池中的线程执行调度由池管理器来处理,当有线程任务时,从池中取一个线程,自行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省系统的资源。
线程池的好处一是通过重复利用已经存在的线程,降低了频繁创建和销毁线程所带来的消耗,因为不用等待创建线程,也提高了程序响应速度。二是线程池统一对线程进行分配和监控,提高了线程的可管理性,也控制了线程的总数,不会无限制地创建线程。

(1) 常见线程池

举个例子:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by 鸣宇淳 on 2017/12/12.
 */
public class Demo1 {
    public static void main(String[] args) {

        //三种线程池
        //      1.创建一个固定大小的线程池,
        //ExecutorService pool= Executors.newFixedThreadPool(3);
        //      2.创建一个单个worker线程的Executors,保证多个线程以指定的顺序执行
        //ExecutorService pool=Executors.newSingleThreadExecutor();
        //      3.创建一个可根据需要创建新线程池。
        ExecutorService pool=Executors.newCachedThreadPool();

        //创建多个线程
        Thread t1=new Thread(new MyThread("线程1"));
        Thread t2=new Thread(new MyThread("线程2"));
        Thread t3=new Thread(new MyThread("线程3"));
        Thread t4=new Thread(new MyThread("线程4"));
        Thread t5=new Thread(new MyThread("线程5"));
        Thread t6=new Thread(new MyThread("线程6"));

        //将线程放入池中执行,向线程池中投放任务
        pool.execute(t1);
        pool.execute(t2);
        pool.execute(t3);
        pool.execute(t4);
        pool.execute(t5);
        pool.execute(t6);

        //关闭线程池
        pool.shutdown();
    }
}


/**
 * Created by 鸣宇淳 on 2017/12/12.
 */
public class MyThread implements Runnable {
    private String name = "";//线程的名字

    public MyThread(String name) {
        this.name = name;
    }

    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(500);
                System.out.println(name + ":正在执行" + i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

这个例子中可以看到:
第一种:定义了一个3个大小的线程池,放入6个线程执行,是前三个先执行,有一个执行完毕后,再执行剩下的,最多有三个线程在执行。
第二种:线程是根据设置的顺序,依次执行的,没有并发的状态。
第三种:会根据运行时的需要,按需创建新的线程。

(2) 延迟线程池

延迟线程池可以设置多长时间后执行某一个线程。
具体看以下实例:


import java.util.Date;

/**
 * Created by 鸣宇淳 on 2017/12/13.
 */
public class ScheduledThreadDemo {
    public static void main(String[] args) {

        //创建一个延时线程池
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);

        Thread t1 = new Thread(new MyThread2("线程1"));
        Thread t2 = new Thread(new MyThread2("线程2"));
        Thread t3 = new Thread(new MyThread2("线程3"));
        Thread t4 = new Thread(new MyThread2("线程4"));

        System.out.println("开始运行时间:" + new Date() + "\n================");

        pool.execute(t1);
        pool.execute(t2);

        //延时5秒后,执行线程t3
        pool.schedule(t3, 5, TimeUnit.SECONDS);
        //延时10秒后,执行线程t4
        pool.schedule(t4, 10, TimeUnit.SECONDS);

        pool.shutdown();
    }
}

public class MyThread2 implements Runnable {
    private String name = "";//线程的名字

    public MyThread2(String name) {
        this.name = name;
    }

    public void run() {
        System.out.println(new Date() + "_" + name + ":正在执行");
    }
}

输出为:

开始运行时间:Wed Dec 13 08:39:13 CST 2017
================
Wed Dec 13 08:39:13 CST 2017_线程1:正在执行
Wed Dec 13 08:39:13 CST 2017_线程2:正在执行
Wed Dec 13 08:39:18 CST 2017_线程3:正在执行
Wed Dec 13 08:39:23 CST 2017_线程4:正在执行

(3) 自定义线程池

举个例子:

/**
 * Created by 鸣宇淳 on 2017/12/13.
 */
public class CustomThreadPool {
    public static void main(String[] args) {
        //创建队列
        BlockingQueue<Runnable> bqueue=new ArrayBlockingQueue<Runnable>(20);

        //创建一个自定义的线程池
        //  1.第一个参数是池中保存的核心线程数
        //  2.第二个参数是池中允许的最大线程数
        //  3.第三个参数是:线程池维护线程所允许的空闲时间。
        //          当线程池中的线程数量大于corePoolSize的时候,
        //          如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,
        //          直到等待的时间超过了keepAliveTime
        //  4.第四个参数为时间单位
        //  5.第五个参数是用于保存线程任务的队列。
        ThreadPoolExecutor pool=new ThreadPoolExecutor(2,5,1000, TimeUnit.MILLISECONDS,bqueue);

        Thread t1 = new Thread(new MyThread2("线程1"));
        Thread t2 = new Thread(new MyThread2("线程2"));
        Thread t3 = new Thread(new MyThread2("线程3"));
        Thread t4 = new Thread(new MyThread2("线程4"));

        pool.execute(t1);
        pool.execute(t2);
        pool.execute(t3);
        pool.execute(t4);

        pool.shutdown();
    }
}
发布了74 篇原创文章 · 获赞 74 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/chybin500/article/details/78785720