线程应用:(六)线程池、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());
}

 

posted @ 2018-08-13 20:50  湮天霸神666  阅读(175)  评论(0编辑  收藏  举报