• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Foreordination
酒后高歌磨剑,梦中快意恩仇,名利脚下踩,情义两肩挑
博客园    首页    新随笔    联系   管理    订阅  订阅
一、线程池

一、线程池

因为每一个线程的启动和结束都是比较消耗时间和占用资源的。如果在系统中用到了很多的线程,大量的启动和结束动作,会导致系统的性能很卡,响应变慢。

线程池的模式很像生产者消费者模式,消费的对象是一个一个的能够运行的任务。

二、思想:

1、准备一个任务容器

2、一次性启动10个消费者线程

3、刚开始任务容器是空的,所以线程都wait在上面

4、直到一个外部线程往这个任务容器中扔一个“任务”,就会有一个消费者线程被唤醒notify。

5、这个消费者线程取出任务,并且执行这个任务,执行完毕后,继承等待下一次任务的到来

6、短时间内,有较多的任务加入,那么就会有多个线程被唤醒,去执行这些任务。

在整个过程中,都不需要创建新的线程,而是循环使用这些已存在的线程。

线程1,运行完毕后,不结束线程,回头又来找新的任务。

建立线程池的代码:

package ThreadPool;
import java.util.LinkedList;
public class ThreadPool{
    //线程池大小
    int threadPoolSize;
    //任务容器
    LinkedList<Runnable> tasks=new LinkedList<Runnable>();
    //试图消费任务的线程
    public ThreadPool(){
        threadPoolSize=10;
        //启动10个任务消费者线程
        synchronized(tasks){
            for(int i=0;i<threadPoolSize;i++){
                new TaskConsumeThread("任务消费者线程"+i).start();
            }
        }
    }
    public void add(Runnable r){
        synchronized(tasks){
            tasks.add(r);
            //唤醒等待的任务消费者线程
            tasks.notifyAll();
        }
    }
    
    class TaskConsumeThread extends Thread{
        public TaskConsumeThread(String name){
            super(name);
        }
        Runnable task;
        
        public void run(){
            System.out.println("启动:"+this.getName());
            while(true){
                synchronized(tasks){
                    while(tasks.isEmpty()){
                        try{
                                tasks.wait();
                        }catch(Exception e){
                            e.printStackTrace();
                        }
                    }
                    task=tasks.removeLast();
                    tasks.notifyAll();
                }
                System.out.println(this.getName()+"获取到任务,并进行");
                task.run();
            }
        }
    }
}
View Code

三、使用java自带的线程池

java提供自带的线程池,不需要自己去开发自定义线程池了

线程池类ThreadPoolExecutor,在包java.util.concurrent下;

使用:ThreadPoolExecutor threadPool=new ThreadPoolExecutor(10,15,60,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>());

详解:第一个参数:表示线程池初始化了10个线程在里面工作

第二个参数:表示如果这10个线程不够用,就会自动增加到最多15个线程

第三个参数:结合TimeUnit.SECONDS,表示经过60秒,多出来的线程还没有接到任务,就会被回收,最后保持池子里就10个线程

第四个参数:表示时间

第五个参数:new LinkedBlockingQueue()用来放任务的集合

package ThreadPool;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPool{
    public static void main(String[] args) throws InterruptedException{
        ThreadPoolExecutor threadPool=new ThreadPoolExecutor(10,15,60,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>());
        threadPool.execute(new Runnable(){//execute()方法用于添加新任务
            public void run(){
                System.out.println("任务1")
            }
        });
    }
}
View Code

 

posted on 2018-02-27 11:25  Foreordination  阅读(166)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3