Java线程池的常用方式

前一篇介绍了Java多线程的创建方式,其中有一种就是通过线程池来启动,这一篇我们一起来聊聊线程池。

先说说什么是线程池:Java提供了一个线程队列,队列中保存着所有等待状态的线程,避免了创建与销毁额外的开销,提高了程序响应速度。

线程池可以解决两个不同问题:由于减少了每个任务调用的开销,它们通常可以在执行大量异步任务时提供增强的性能,并且还可以提供绑定和管理资源(包括执行任务集时使用的线程)的方法。每个 ThreadPoolExecutor 还维护着一些基本的统计数据,如完成的任务数。

线程池的体系结构如下:

    java.util.concurrent.Executor : 负责线程的使用与调度的根接口
      |--ExecutorService 子接口: 线程池的主要接口
         |--ThreadPoolExecutor 线程池的实现类
         |--ScheduledExecutorService 子接口:负责线程的调度
            |--ScheduledThreadPoolExecutor :继承 ThreadPoolExecutor, 实现 ScheduledExecutorService

JavaApi推荐大家直接使用 Executors 这个工具类,里面封装了很多方便的工具方法,下面就通过它来讲解创建线程的具体方式:

第一种:

  • Executors.newCachedThreadPool()(自动缓存无界线程池),根据需要创建新的线程,在可用时将重用先前构建的线程,如果没有空闲的线程,将创建一个新的线程,并添加到池中,池中默认超过六十秒空闲的线程被终止并从缓存中移除。

public class TestCachedThreadPool {

    public static void main(String[] args) {
        try{
            ExecutorService pool = Executors.newCachedThreadPool();
            for (int i=0;i<5;i++){
                pool.submit(new TestThread());
            }
            pool.shutdown();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

class TestThread implements Runnable{

    @Override
    public void run() {
         System.out.println("当前线程名称:"+Thread.currentThread().getName());
    }

}

循环5次,创建5个线程,可以看到执行结果如下,每次都是新启的线程:

循环为10次,结果如下:

第二种:

    

public class TestThreadPoolTwo {

    public static void main(String[] args) {
        try {
            //1. 创建线程池
            ExecutorService pool = Executors.newFixedThreadPool(3);
            ThreadPoolDemoTwo tpd = new ThreadPoolDemoTwo();
            //2. 为线程池中的线程分配任务
            for (int i = 0; i < 5; i++) {
                pool.submit(tpd);
            }
            //3. 关闭线程池
            pool.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class ThreadPoolDemoTwo implements Runnable {
    @Override
    public void run() {
        System.out.println("当前线程名字:" + Thread.currentThread().getName());
    }
}

执行结果如下,只会创建3个线程,循环调用:

第三种:

  • Executors.newSingleThreadExecutor()(单个后台线程),即该种方法只会创建一个线程

    public class TestSingleThreadPool {
    
        public static void main(String[] args) {
            try{
                ExecutorService pool = Executors.newSingleThreadExecutor();
                for (int i=0;i<10;i++){
                    pool.submit(new TestThread());
                }
                pool.shutdown();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    
    class TestThread implements Runnable{
    
        @Override
        public void run() {
             System.out.println("当前线程名称:"+Thread.currentThread().getName());
        }
    
    }

    执行结果如下,循环调用池中线程处理业务:

        

第四种:

  •  Executors.newScheduledThreadPool(调度线程池),该种方法可以创建固定大小并可以设置延迟执行的线程池
    public class TestScheduledThreadPool {
    
    	static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
    	public static void main(String[] args) throws Exception {
    		ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
    		
    		for (int i = 0; i < 5; i++) {
    			Future<Integer> result = pool.schedule(new Callable<Integer>(){
    
    				@Override
    				public Integer call() throws Exception {
    					int num = new Random().nextInt(100);//生成随机数
    					System.out.println("当前时间:"+sdf.format(new Date())+"当前线程名称:"+Thread.currentThread().getName() + "随机数 : " + num);
    					return num;
    				}
    				
    			}, 1, TimeUnit.SECONDS);
    
    			System.out.println("计算的结果:"+result.get());
    		}
    		
    		pool.shutdown();//关闭线程池
    	}
    }

    执行结果:

       

以上就是Executors工具类提供的常用创建线程池方法,希望能帮助到学习Java多线程的小伙伴。

欢迎各们小伙伴加群交流,期待你们的加入,群号:1077176637

发布了8 篇原创文章 · 获赞 0 · 访问量 128

猜你喜欢

转载自blog.csdn.net/ka530888/article/details/104884920