zoukankan      html  css  js  c++  java
  • 线程应用:(六)线程池、Callable与Future

    一、线程池

      TCP服务器编程模型中,每来一个客户端连接时,服务端就要创建一个新线程为之服务,当与客户端的会话结束时,线程也就结束了。

      在线程池的编程模式下,任务是提交给整个线程池,而不是直接交给某个线程,线程池在拿到任务后,它就在内部找有无空闲线程,再把任务交给内部某个空闲的线程,一个线程同时只能执行一个任务,但可以向线程池提交多个任务。

      池子里只有3个线程,但有10个任务,所以只有三个任务会被执行,当3个任务执行完,再由线程池对线程分配任务。

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    public class Thread1 {
        public static void main(String[] args) {
        //new单一线程池,线程池只有一个线程,但是这个线程死了,会自动补新的线程    
            //ExecutorService threadPool= Executors.newSingleThreadExecutor();
            
        //new固定数量的线程池
            ExecutorService threadPool= Executors.newFixedThreadPool(3);
        
        //new缓存的线程池,内部线程个数不定,任务大于线程个数时,自动增加新的线程,任务小于线程个数时,收回线程
            //ExecutorService threadPool= Executors.newCachedThreadPool();
            //往池子丢10任务,每个对象是一个Runnable
            for(int i=1;i<=10;i++){        
                final int task = i;    
                threadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        for(int j=1;j<=10;j++){
                            System.out.println(Thread.currentThread().getName()+", looping:"+j+", task:"+task);
                        }
                    }
                });
            }
            
            threadPool.shutdown();        //任务都执行完,关闭线程池
            //threadPool.shutdownNow();    //立即结束线程
        }
    }
    线程池定时器。
    //线程池设置了3个线程,一个任务,10s后运行
    //线程池定时器,但是这种定时器没有固定时间的定时,要定时凌晨3点,可以把凌晨3点的时间-现在时间
    Executors.newScheduledThreadPool(3).schedule(
            new Runnable() {
                @Override
                public void run() {
                    System.out.println("boom!!!");
                }
            }, 
            10,                   //常量
            TimeUnit.SECONDS);    //单位

    二、Callable与Future

    1)无返回值的情况:用前面execute的方式执行任务是无返回结果的。
    2)有返回值的情况:用submit方式,传任务Callable,运行完后返回Future

    ExecutorService threadPool = Executors.newSingleThreadExecutor();
    Future<String> future = 
        threadPool.submit(
                new Callable<String>() {
                    @Override
                    public String call() throws Exception {
                        return "hello";
                    }
                }
        );
    
    //future如果还没结果,会一直等,有点鸡肋
    System.out.println(future.get());

      CompletionService用于得到一组返回结果。

    //CompletionService可以获得一组返回结果
    //创建一个有10个线程的线程池
    ExecutorService threadPool= Executors.newFixedThreadPool(10);
    CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool);
    //提交10个任务
    for(int i=1;i<=10;i++){
        final int seq = i;
        completionService.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    Thread.sleep(new Random().nextInt(5000));    //让每个任务运行时间不同
                    return seq;
                }
            }
        );
    }
    
    //取返回结果,最先拿到运行完的
    for(int i=0;i<10;i++){
        System.out.println(completionService.take().get());
    }
  • 相关阅读:
    归并两路有序链表
    [转]两种高性能I/O设计模式(Reactor/Proactor)的比较
    linux 静态库使用经验
    系统性能调优经验
    编译-O 选项对性能提升作用
    [转]Linux shell中的那些小把戏
    shell函数传递带空格的参数
    标题清洗引发的算法(两个字符串的最长公共子串)
    正则表达式之Matcher类中group方法
    ConcurrentHashMap JDK 1.6 源码分析
  • 原文地址:https://www.cnblogs.com/zjxiang/p/9425102.html
Copyright © 2011-2022 走看看