java笔记2.4--线程池

可能遇到的问题:

1.为什么要用线程池?避免因线程切换造成的性能损耗。

2.构造线程池时,你关注哪些参数?

3.线程池时如何接受并处理任务的?任务满了以后怎么办?

4.在使用线程池时,如何避免OOM异常?

基本用法:

定义Runnable(没有返回值)或者Callable(可以有返回值)类型的任务

创建ThreadPoolExector,注意参数

把任务放进线程池运行

通过shutdown方法关闭,即不接受新任务,当前线程执行完后退出。

class MyThread extends Thread{
    private String name;

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

    public void run(){
        System.out.println("Thread: " + name + " start ");
        try {
            sleep(5000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("Thread "+ name + " finnish");
    }
}
public class ThreadPoolDemo {
    public static void main(String[] args){
        //创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2,4,200,
                TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(5));

        for (int i = 0; i < 5; ++i){
            MyThread mytast = new MyThread(Integer.valueOf(i).toString());
            //加入线程池
            executor.execute(mytast);
        }
        //关闭
        executor.shutdown();
    }
}
运行结果:
Thread: 0 start 
Thread: 1 start 
Thread 0 finnish
Thread 1 finnish
Thread: 3 start 
Thread: 2 start 
Thread 3 finnish
Thread 2 finnish
Thread: 4 start 
Thread 4 finnish

创建线程池后,线程数为0,有任务就会创建一个线程去执行,当达到corePoolSize(第一个参数:2)时,会把新的任务放到缓存队列。
maximumPlloSize(第二个参数:4)表示线程池中最多能创建多少个线程。
keepAliveTime(第三个参数:200)表示线程没有执行任务时最多保持多久时间会终止unit(第四个参数:TimeUnit.MILLISECONDS)为时间单位。workQueue(第五个参数:new ArrayBlockingQueue<Runnable>(5))为阻塞队列,用来存储等待执行的任务。
本实例没有的参数:第七个参数hander : 拒绝处理任务时的侧缺,有4个取值,常用的是丢弃任务抛异常(也是默认参数AbortPolicy),悄悄丢弃(Discardpolicy)

创建线程池后,没有线程,直到任务到来,达到设置Size后,再来就放入queue队列,如果该队列有界,最大就maxSize,如果无界,任务一直放进队列,导致OOM。

扩展顺序:新建的线程先放入线程池corePoolSize(第一个参数:2),从第三个开始放入缓冲队列workQueue(第五个参数:new ArrayBlockingQueue<Runnable>(5))。此时这个也满了,从第8个开始由这个参数(maximumPlloSize - corePoolSize)控制可建几个线程、
 

class Task implements Runnable{
    private int num;

    public Task(int num){
        this.num = num;
    }

    public void run(){
        System.out.println("the tast "+ num + " is running");
        try {
            Thread.currentThread().sleep(5000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("tast " + num + " finished");
    }
}
public class PoolParamDemo {
    public static void main(String[] args){
        ThreadPoolExecutor executor = new ThreadPoolExecutor(5,10,200,
                TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(5));

        for (int i = 0; i < 8; ++i){
            Task task = new Task(i);
            executor.execute(task);
            System.out.println("The thread number in Thread Poss is:" + executor.getPoolSize() + ", the queue length is: "+
                    executor.getQueue().size() + ", finished thread num is: " + executor.getCompletedTaskCount());
        }
        executor.shutdown();
    }
}
运行结果:
the tast 0 is running
The thread number in Thread Poss is:1, the queue length is: 0, finished thread num is: 0
The thread number in Thread Poss is:2, the queue length is: 0, finished thread num is: 0
the tast 1 is running
The thread number in Thread Poss is:3, the queue length is: 0, finished thread num is: 0
the tast 2 is running
The thread number in Thread Poss is:4, the queue length is: 0, finished thread num is: 0
The thread number in Thread Poss is:5, the queue length is: 0, finished thread num is: 0
the tast 3 is running
The thread number in Thread Poss is:5, the queue length is: 1, finished thread num is: 0
The thread number in Thread Poss is:5, the queue length is: 2, finished thread num is: 0
the tast 4 is running
The thread number in Thread Poss is:5, the queue length is: 3, finished thread num is: 0
tast 0 finished
the tast 5 is running
tast 2 finished
tast 1 finished
the tast 7 is running
the tast 6 is running
tast 4 finished
tast 3 finished
tast 5 finished
tast 7 finished
tast 6 finished

说辞:

消息发布模块,通过线程池处理消息。

如果不慎把workQueue设置无界会导致:

CAT监控内存,不定期内存用量偏高。

业务高峰时不定期OOM

解决:用Dump保存内存镜像,用JMAT分析,最终定位到线程池配置参数,修改为有界队列,合理设置拒绝策略。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值