多线程编程(三)

1、线程池:

 - 防止大量执行异步任务时,频繁的创建和销毁线程对象带来的系统开销;
 - 根据线程池类型的不同可以有效防止系统中的线程资源消耗过多;

2、线程池核心参数:

 - corePoolSize:线程池核心线程个数(包括空闲线程)
 - maximunPoolSize:线程池中线程的最大数量
 - workQueue:存放execute方法提交的任务的阻塞队列(BlockingQueue),如:
 		synchronousBlockingQueue、ArrayBlockingQueue、LinkedBlockingQueue等。
 - ThreadFactory:创建线程的工厂
 - keepAliveTime:线程池中线程数量超过corePoolSize时,池中空闲线程的存活时间
 - unit:keepAliveTime的单位
 - RejectExecutionHandler:任务拒绝策略

3、类结构:
在这里插入图片描述
4、常见线程池的种类:

 - newSingleThreadExecutor()
 - newFixedThreadPool(n)
 - newCachedThreadPool()
 - newScheduledThreadPool()
 注:以上几种线程池类型均是由于设置的corePoolSize、maximunPoolSize、workQueue类型
 以及RejectExecutionHandler产生的结果。

5、线程池的状态(volatile int runState):

static final int RUNNING = 0;//运行状态
static final int SHUTDOWN = 1;//显式执行shutdown()方法后的状态,仍会执行完所有
								workQueue中的所有任务
static final int STOP = 2;//显式调用shutDownNow()方法后的状态,workQueue中的任
							务不再执行且尝试终止正在执行的任务
static final int TERMINATED = 3;//所有任务执行完毕,线程池中的全部工作线程销毁完毕

6、线程池的核心方法:

execute()
submit()
shutdown()
shutdownNow()

7、任务缓存策略:

 - 立即提交策略:使用synchronousBlockingQueue工作队列,execute方法执行提交的任务不
 			会缓存提交的任务,直接在创建线程执行,要求maximumPoolSize足够大。
 - 无界队列策略:使用LinkedBlockingQueue工作队列,任务被提交时如果线程池中的线程数
 			小于corePoolSize时,直接创建线程执行;如果线程数 >= corePoolSize时,
 			优先向工作队列中添加,等待工作线程执行,如:newFixedThreadPool
 - 有界队列策略:使用ArrayBlockingQueue工作队列,当任务队列已满且线程数已达到最大值
 			选择丢弃任务。

8、任务拒绝策略:

 - ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常
 - ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
 - ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
 - ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务 

9、测试代码:

(1)newSingleThreadExecutor:
public class ThreadPoolTest {
    public static void main(String[] args){
        ExecutorService executor = Executors.newSingleThreadExecutor();
        MyThread thread0 = new MyThread();
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();

        executor.execute(thread0);
        executor.execute(thread1);
        executor.execute(thread2);
        System.out.println("线程池状态改变");
    }

    static class MyThread implements Runnable{

        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName());
        }
    }
}
执行结果:
	线程池状态改变
	pool-1-thread-1
	pool-1-thread-1
	pool-1-thread-1
  可以看到所有的任务是由同一个线程执行的。
(2)newFixedThreadPool():
public class ThreadPoolTest {
    public static void main(String[] args){
        ThreadPoolExecutor executor = (ThreadPoolExecutor)(Executors.newFixedThreadPool(3));
        MyThread thread0 = new MyThread();
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        MyThread thread3 = new MyThread();
        MyThread thread4 = new MyThread();

        executor.execute(thread0);
        System.out.println(executor.getPoolSize());
        executor.execute(thread1);
        System.out.println(executor.getPoolSize());
        executor.execute(thread2);
        System.out.println(executor.getPoolSize());
        executor.execute(thread3);
        System.out.println(executor.getPoolSize());
        executor.execute(thread4);
        System.out.println(executor.getPoolSize());
        executor.shutdown();
        System.out.println("线程池状态改变");
    }

    static class MyThread implements Runnable{

        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName());
        }
    }
}
执行结果:
	1
	2
	3
	3
	3
	线程池状态改变
	pool-1-thread-1
	pool-1-thread-2
	pool-1-thread-3
	pool-1-thread-1
	pool-1-thread-2
可以看到线程池中的线程数最多保持在3个。
(3)newCachedThreadPool():
public class ThreadPoolTest {
    public static void main(String[] args){
        ThreadPoolExecutor executor = (ThreadPoolExecutor)(Executors.newCachedThreadPool());
        MyThread thread0 = new MyThread();
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        MyThread thread3 = new MyThread();
        MyThread thread4 = new MyThread();

        executor.execute(thread0);
        System.out.println(executor.getPoolSize());
        executor.execute(thread1);
        System.out.println(executor.getPoolSize());
        executor.execute(thread2);
        System.out.println(executor.getPoolSize());
        executor.execute(thread3);
        System.out.println(executor.getPoolSize());
        executor.execute(thread4);
        System.out.println(executor.getPoolSize());
        executor.shutdown();
        System.out.println("线程池状态改变");
    }

    static class MyThread implements Runnable{

        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName());
        }
    }
}
执行结果:
	1
	2
	3
	4
	5
	线程池状态改变
	pool-1-thread-1
	pool-1-thread-2
	pool-1-thread-3
	pool-1-thread-4
	pool-1-thread-5
可以从结果看到每一个任务都是由不同的线程执行的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值