线程池2

Posted changzuidaerguai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程池2相关的知识,希望对你有一定的参考价值。

Executor

/*
 * Executor是一个接口,需要使用它的实现类ThreadPoolExecutor,这里用Executors.newSingleThreadExecutor()返回一个单线程池
 * execute()方法传入的是一个Runnable对象
 * */
public class ExecutorsJava {
    public static void main(String[] args) {
        Executor e = Executors.newSingleThreadExecutor();
        e.execute(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                while(true) {
                    System.out.println("线程1正在执行");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        });
    }
}

ExecutorService
ExecutorService相比Executor多了实现执行Callable多线程的方法,以及提供了具有返回值的执行方法

public class ExecutorServiceJava {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        // ExecutorService是接口,需要使用实现类ThreadPoolExecutor对象
        ExecutorService es = Executors.newCachedThreadPool();
        CallableTest ct = new CallableTest();
        //把Callable多线程传入线程池中,并得到包装返回值信息的Future
        Future<String> f = es.submit(ct);
        System.out.println("从future中获取信息:" + f.get());
    }

}

class CallableTest implements Callable<String>{

    @Override
    public String call() throws Exception {
        // TODO Auto-generated method stub
        return Thread.currentThread().getName() + "---线程正在执行---";
    }
    
}

也可以传入Runnable对象并设置执行完成返回值

public class ExecutorServiceJava {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService es = Executors.newCachedThreadPool();
        RunnableTest rt = new RunnableTest();
        //把Runnable对象传入,并设置返回值
        Future<String> f = es.submit(rt, "执行完成");
        System.out.println("从future中获取信息:" + f.get());
    }

}
//------------------------------------------------------------------------------------------
class RunnableTest implements Runnable{
    private static int i = 5;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        b:
        while(true) {
            if(i > 0) {
                System.out.println(Thread.currentThread().getName() + "---Runnable线程正在执行---");
                i--;
            }else {
                break b;
            }
        }
        
    }
    
}

执行线程集合

public class ExecutorServiceJava {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService es = Executors.newCachedThreadPool();
        //储存返回结果对象
        List<Future<String>> lf = new ArrayList<>();
        CallableTest ct1  = new CallableTest();
        CallableTest ct2  = new CallableTest();
        CallableTest ct3  = new CallableTest();
        CallableTest ct4  = new CallableTest();
        //把要执行的线程存入集合中
        Collection<CallableTest> collection = new HashSet<>();
        collection.add(ct1);
        collection.add(ct2);
        collection.add(ct3);
        collection.add(ct4);
        //执行多线程
        lf = es.invokeAll(collection);
        //迭代并得到结果
        for(Future<String> f : lf) {
            System.out.println(f.get());
        }
    }

}

class CallableTest implements Callable<String>{

    @Override
    public String call() throws Exception {
        // TODO Auto-generated method stub
        return Thread.currentThread().getName() + "---Callable线程正在执行---";
    }
    
}

invokeAny()方法与invokeAll()区别在于invokeAny()随便执行一个有返回值就退出,也就是只会执行一个线程

        String lf2 = es.invokeAny(collection);
        System.out.println( "随便执行一个" + lf2);

ThreadPoolExecutor实现了ExecutorService和Executor接口的
ScheduledThreadPoolExecutor

schedule(Callable<V> callable, long delay, TimeUnit unit) 创建并执行在给定延迟后启用的 ScheduledFuture。

schedule(Runnable command, long delay, TimeUnit unit) 创建并执行在给定延迟后启用的一次性操作。

scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) 创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,然后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。 

ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)  创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。 

这四个方法实现定时操作

FutureTask
FutureTask类实现了RunnableFuture接口,RunnableFuture接口实现了Runnable、Future。也就是FutureTask可以当做一个线程使用,同时也可以作为线程的返回结果。
FutureTask提供了两个构造器

public FutureTask(Callable<V> callable) {}
public FutureTask(Runnable runnable, V result) {}

程序示例:

/*
 * 执行结果:
 *  子线程在进行计算
 *  主线程开始执行
 *  4950
 *  主线程执行完成
 * 执行顺序:
 *  子线程
 *  主线程
 *  主线程获取子线程结果
 *  主线程执行完成
 * */
public class FutureTaskJava {

    public static void main(String[] args) throws InterruptedException {
        
        //新建异步任务
        CallableFutureTask cj = new CallableFutureTask();
        FutureTask<Integer> ft = new FutureTask<>(cj);
        //创建线程池
        ExecutorService es = Executors.newCachedThreadPool();
        //异步任务完成
        es.submit(ft);
        es.shutdown();
        
        Thread.sleep(1000);
        
        System.out.println("主线程开始执行");
        try {
            System.out.println(ft.get());
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("主线程执行完成");
    }

}
class CallableFutureTask implements Callable<Integer>{

    @Override
    public Integer call() throws Exception {
          System.out.println("子线程在进行计算");
            Thread.sleep(3000);
            Integer sum = 0;
            for(int i=0;i<100;i++)
                sum += i;
            return sum;
        }
    }
    
    

Future模式的核心在于:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑
FutureTask在高并发环境下确保任务只执行一次
Timer和TimerTask

public class TimerJava {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Timer t = new Timer();
        t.schedule(new TimerTask() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                System.out.println("TimerTask正在执行--");
            }
            //1000毫秒以后执行,每1000毫秒执行一次
        }, 1000, 1000);
    }   

}






以上是关于线程池2的主要内容,如果未能解决你的问题,请参考以下文章

线程池与并行度

Java——线程池

Motan在服务provider端用于处理request的线程池

Java线程池详解

Java线程池详解

Java 线程池详解