多线程(十二)--线程池--自定义线程池

 

 

1.有界队列的使用

public class MyTask implements Runnable {

    private int taskId;
    private String taskName;

    public MyTask(int taskId, String taskName) {
        this.taskId = taskId;
        this.taskName = taskName;
    }

    @Override
    public void run() {
        try {
            System.out.println("run taskId=" + taskId);
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public int getTaskId() {
        return taskId;
    }

    public void setTaskId(int taskId) {
        this.taskId = taskId;
    }

    public String getTaskName() {
        return taskName;
    }

    public void setTaskName(String taskName) {
        this.taskName = taskName;
    }

    @Override
    public String toString() {
        return Integer.toString(taskId);
    }
}
import java.util.concurrent.*;

public class UseThreadPoolExecutor1 {
    public static void main(String[] args) {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                1,
                2,
                60,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(3)
        );

        MyTask mt1 = new MyTask(1, "任务1");
        MyTask mt2 = new MyTask(2, "任务2");
        MyTask mt3 = new MyTask(3, "任务3");
        MyTask mt4 = new MyTask(4, "任务4");
        MyTask mt5 = new MyTask(5, "任务5");
        MyTask mt6 = new MyTask(6, "任务6");

        pool.execute(mt1);
        pool.execute(mt2);
        pool.execute(mt3);
        pool.execute(mt4);
        pool.execute(mt5);
        pool.execute(mt6);

        pool.shutdown();

    }
}

线程池提交的时候,分别试验,提交1个,提交2个,提交3个,提交5个,提交6个。

 

2.无界队列的使用

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class UseThreadPoolExecutor2 implements Runnable {

    private static AtomicInteger count = new AtomicInteger(0);

    @Override
    public void run() {
        try {
            int temp = count.incrementAndGet();
            System.out.println("任务" + temp);
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
//        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(10);
        ExecutorService pool = new ThreadPoolExecutor(
                5,
                10,
                120L,
                TimeUnit.SECONDS,
                queue);
        for (int i = 0; i < 20; i++) {
            pool.execute(new UseThreadPoolExecutor2());
        }

        Thread.sleep(1000);
        System.out.println("queue size: " + queue.size());
        Thread.sleep(2000);
    }
}

使用无界队列时,maxPoolSize就不生效了。

3.拒绝策略

AbortPolicy: 抛出一个异常,系统可以继续正常运行(jdk默认的拒绝策略)

DiscardOldestPolicy,看一个例子

public class UseThreadPoolExecutor1 {
    public static void main(String[] args) {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                1,
                2,
                60,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(3),
                new ThreadPoolExecutor.DiscardOldestPolicy()
        );

        MyTask mt1 = new MyTask(1, "任务1");
        MyTask mt2 = new MyTask(2, "任务2");
        MyTask mt3 = new MyTask(3, "任务3");
        MyTask mt4 = new MyTask(4, "任务4");
        MyTask mt5 = new MyTask(5, "任务5");
        MyTask mt6 = new MyTask(6, "任务6");

        pool.execute(mt1);
        pool.execute(mt2);
        pool.execute(mt3);
        pool.execute(mt4);
        pool.execute(mt5);
        pool.execute(mt6);

        pool.shutdown();

    }
}

第2个任务被丢掉了。

我们来推演一下。第1个任务提交之后,唯一的核心线程进行处理。第2、3、4个线程进入有界队列。第5个任务提交的时候,队列满,创建新的线程,此时达到了maxPoolSize。第6个线程提交的时候,2号线程是队列中最老线程,丢弃。然后6号线程重新提交,入队列。

 

自定义拒绝策略

import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

public class MyReject implements RejectedExecutionHandler {

    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        System.out.println("自定义处理...");
        System.out.println("当前被拒绝任务为:" + r.toString());

        //在实际的业务场景中,可以用以下方式
        //1.用http传json的方式,发送给数据源服务器,告诉它这个任务被拒绝了,下次可以重发。
        //2.记录日志,暂缓到一个地方,之后,再跑一个定时的job,把这些没处理的任务再处理一遍。
        //3.不管成功与否,都记录一下日志
        //真实的工作中,一般都是先记录日志,稍后再去处理
    }
}
import java.util.concurrent.*;

public class UseThreadPoolExecutor1 {
    public static void main(String[] args) {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                1,
                2,
                60,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(3),
                new MyReject()
        );

        MyTask mt1 = new MyTask(1, "任务1");
        MyTask mt2 = new MyTask(2, "任务2");
        MyTask mt3 = new MyTask(3, "任务3");
        MyTask mt4 = new MyTask(4, "任务4");
        MyTask mt5 = new MyTask(5, "任务5");
        MyTask mt6 = new MyTask(6, "任务6");

        pool.execute(mt1);
        pool.execute(mt2);
        pool.execute(mt3);
        pool.execute(mt4);
        pool.execute(mt5);
        pool.execute(mt6);

        pool.shutdown();

    }
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值