线程池使用

当一个线程start()之后,是在run方法里通过wait()、sleep()等方法来改变状态,而线程池是改不了线程的状态的,线程池的作用是用来管理这些线程何时开启start,还没开启的线程怎么排队,优先级是怎样的,线程池就是做这些工作。

下面来自定义一个线程池,首先定义一个接口,接口方法实现两个方法,加入Runnable对象和删除:

public interface IThreadPool {
    void add(Runnable runnable);
    void remove();
}

然后定义这个线程池:

public class ThreadPoolImpl  implements  IThreadPool{

    private static int WORK_NUM = 2;//线程池内的工作线程数为2

    private static PriorityBlockingQueue<Runnable> blockingQueue = new PriorityBlockingQueue<>();//线程队列

    @Override
    public void add(Runnable runnable) {

    }

    @Override
    public void remove() {

    }
}


首先实现IThreadPool接口,然后定义了一个固定线程(也就是该线程池里一直工作运行的线程)数量为2,还定义了一个权限队列(具有优先级PriorityBlockingQueue)blockingQueue 。接下来定义这个工作线程:

class ThreadPoolWorkerThread extends Thread{

        private boolean isRunning = true;

        @Override
        public void run() {
            while (isRunning) {
                synchronized (ThreadPoolWorkerThread.class) {
                    try {
                        Runnable runnable = blockingQueue.take();
                        //取出线程后执行它的run逻辑
                        runnable.run();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }


线程池里的工作线程是为了从队列里取出线程然后进行它们各自的run方法,而这个过程是需要同步,所以使用了synchronized锁(根据之前分析的锁机制可以根据实际情况来优化)。那什么时候来开启这些工作线程,当然是外部在构造线程池的时候开启这些工作线程,所以ThreadPoolImpl 的构造方法:

public ThreadPoolImpl() {
        for (int i = 0; i < WORK_NUM; i++) {
            ThreadPoolWorkerThread thread = new ThreadPoolWorkerThread();
            thread.start();
        }
}

当外部Activity构造ThreadPoolImpl对象的时候就构造出线程池内部两个工作线程然后让它们启动起来,别忘了线程池的添加线程方法:

    @Override
    public void add(Runnable runnable) {
        //这里可以根据实际要求设置一个添加数据的限制

        blockingQueue.add(runnable);
    }

正如注释所说那样,如果实际需要线程池的队列数量有限制,可以在此之前判断一下然后才进行添加。基本上整个线程池的创建思路就是这些,另外一些优化和补充的功能和细节则要根据实际开发需求来定,最后外部Activity要使用该线程池则如下:

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        IThreadPool threadPool =  new ThreadPoolImpl();
        for (int i = 0; i < 10; i++) {
            threadPool.add(new Task("线程" + i));
        }
    }

    static class Task implements Runnable{
        private String name;

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

        @Override
        public void run() {

        }
    }
}


代码不难,相信大家都能理解,在构造线程池的时候,就已经让它里面的工作线程启动,然后不断轮询队列里的线程,而队列里的线程则通过外部调用者来添加进去,删除线程的方法也是外部去操纵线程池的remove方法。另外有一点要说明一下,虽然在工作线程里不断轮询去从队列里取线程的时候会有阻塞(加了锁),但因为工作线程本身也是子线程,所以不会阻塞到主线程(UI线程)了
————————————————
版权声明:本文为CSDN博主「Pingred_hjh」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_39867049/article/details/127766734

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csdn_zxw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值