Java线程(线程池、创建线程的第三种方法callable)续上一章

线程池

补充资料:Doug Lea (JCP组织的一人)对线程池部分贡献巨大

常用线程池的接口和类:

Executor:线程池的顶级接口

ExecutorService:线程池接口可用submit(Runnable Task)提交任务代码。包含:Shutdown;

Shutdownnow等

Executors工厂类:可以通过这一个方法得到一个线程池

NewFixedThreadPool(int n Thread):获取固定数量的线程池。参数:指线程池中线程的数量

NewCacheThreadPool()获取动态数量的线程池,无上限

对于ExecutorService:需关注实现类TheadPoolExecutor,SheduledThreadPoolExecutor

Executors:1.创建固定线程个数的线程池

2.创建缓存线程池,又任务多少来决定

3.创建单线程池

4.创建调度线程池  调度:周期、定时执行

在API中:

Shutdown:启动一次顺序关闭,执行以前提交的任务,但不接受新任务

ShutDownNow:试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表

代码示例1 固定线程个数:

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;


public class Demo {

    public static void main(String[] args) {

//        1.创建固定线程个数的线程池

        ExecutorService es=Executors.newFixedThreadPool(4);

//        2.提交任务

        Runnable run=new Runnable() {

            private int ticket;


            @Override

            public void run() {

                while (true) {

                    if (ticket <= 0) {

                        break;

                    }

                    System.out.println(Thread.currentThread().getName() + "卖完第:" + ticket + "张票");

                    ticket--;

                }

            }

        };

//        3.提交任务

                for(int i=0;i<=4;i++) {

            es.submit(run);

        }

//        4.关闭线程池

        es.shutdown();

        }

}

代码示例 2 可变线程个数,由任务决定

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;


public class Demo {

    public static void main(String[] args) {

//        1.创建固定线程个数的线程池

//        ExecutorService es=Executors.newFixedThreadPool(4);

        ExecutorService es2=Executors.newCachedThreadPool();

//        2.提交任务

        Runnable run=new Runnable() {

            private int ticket;


            @Override

            public void run() {

                while (true) {

                    if (ticket <= 0) {

                        break;

                    }

                    System.out.println(Thread.currentThread().getName() + "卖完第:" + ticket + "张票");

                    ticket--;

                }

            }

        };

//        3.提交任务

                for(int i=0;i<=4;i++) {

            es2.submit(run);

        }

//        4.关闭线程池

        es2.shutdown();

        }

}

注:提交任务数不一定是4.要具体看运行结果

Excutors的另外两种方法

3. ExecutorService e3=Executors.newSingleThreadExecutor();
4. ExecutorService e4=Executors.newScheduledThreadPool();

Callable接口

语法:

Public interface Callable<V>{public V call() throws Exception}

特点:有返回值;使用时需要先转化为任务后被Thread调用

代码示例:

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.Future;

import java.util.concurrent.FutureTask;


public class Demo02 {

    public static void main(String[] args) {

//        功能需求:计算1-100的和并使用Callable接口

        Callable<Integer> callable=new Callable<Integer>() {

            @Override

            public Integer call() throws Exception {

                System.out.println(Thread.currentThread().getName()+"开始计算");

                int sum = 0;

                for (int j = 1;j<=100;j++){

                    sum+=j;

                    Thread.sleep(100);

                }

                return sum;


            }

        };

//        把Callable转化为可执行的任务

        FutureTask<Integer> task = new FutureTask<>(callable);


//        创建线程

        Thread thread = new Thread(task);


//        启动线程

        thread.start();


//        获取结果

        Integer sum= null;

        try {

            sum = task.get();

        } catch (InterruptedException e) {

            e.printStackTrace();

        } catch (ExecutionException e) {

            e.printStackTrace();

        }

        System.out.println("结果是"+sum);

        }

}

Callable与线程池的结合的使用

这种方法与线程池的配合更为紧密

优点:无需先转化为task,再进行执行;

需求示例:使用Callable和线程池计算1-100的和

代码示例:

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;


public class Demo03 {

    public static void main(String[] args) throws Exception {

//        1. 创建线程池

        ExecutorService es = Executors.newFixedThreadPool(1);

//        2.提交任务Future:表示将要执行任务的结果

        Future<Integer> future =  es.submit(new Callable<Integer>() {

            @Override

            public Integer call() throws Exception {

                System.out.println(Thread.currentThread().getName()+"开始计算");

                int sum=0;

                for (int i=0;i<=100;i++){

                    sum+=i;

                }

                return sum;

            }

        });

//        3.获取任务结果

       System.out.println(future.get());


//        4.关闭线程池

        es.shutdown();

    }

}

Future接口

功能:表示将要完成的任务的结果

案例需求:使用两个线程,并发计算1-50和51-100的和,再进行汇总统计

Future.get()方法需要等待callable的方法执行完毕才可以继续执行,即 同步

关于同步、异步:我们现在手头有两个线程A\B,A在使用过程中会调用B线程。同步的含义是例如A需要执行三个部分,在第一个部分时调用了B,调用之后不继续执行第二个部分而是等待B被调用完之后再继续执行第二第三个部分。

异步的含义是,A执行第一部分并调用了B线程,A不继续等待B线程执行完而接着执行第二部分第三部分。

代码示例:

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;


public class Demo4 {

    public static void main(String[] args) throws Exception{

//        1.创建线程池

        ExecutorService es = Executors.newFixedThreadPool(2);

//        2.创建任务及对象

        Future<Integer> future =es.submit(new Callable<Integer>() {

            @Override

            public Integer call() throws Exception {

                int sum=0;

                for(int i=0;i<=50;i++){

                    sum+=i;

                }

                return sum;

            }

        });


        Future<Integer> future2=es.submit(new Callable<Integer>() {

            @Override

            public Integer call() throws Exception {

                int sum=0;

                for(int i=51;i<=100;i++){

                    sum+=i;

                }

                return sum;

            }

        });

//      3.获取结果

        int sum=future.get()+future2.get();

        System.out.println("结果是" + sum);


//        4.关闭线程

        es.shutdown();

    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逃逸线LOF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值