Java开发——40.多线程_(JDK5.0-线程池/实现Callable接口,创建线程)

进程:系统分配资源的单位;
线程:处理器任务调度和执行的单位,线程之间共享进程资源。

学习大纲:
在这里插入图片描述

创建线程:

一、继承Thread类

二、实现Runnable接口

三、创建线程池:

线程池需要了解一个类和一个接口:Executors:工具类、线程池的工厂类;ExecutorService:真正的线程池接口,其子类为ThreadPoolExecutor。
池:即使池子(Pool),即我们可以在线程池中定义多个线程。

Executors:

工具类、线程池的工厂类,用于创建并返回不同类型的线程池

Executors.newCachedThreadPool():创建一个可根据需要创建新线程的线程池
Executors.newFixedThreadPool(n):创建一个可重用固定线程数的线程池

Executors.newSingleThreadExecutor() :创建一个只有一个线程的线程池
Executors.newScheduledThreadPool(n):创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。

ExecutorService:

真正的线程池接口,需要掌握三个方法。

在这里插入图片描述

方法详情:

execute(Runnable runnable):只能用来实现Runnable接口
sumbit(Callable callable):一般用来实现Callable接口,但是也可是实现Runnable接口
showdown():关闭连接池

想知道Callable是什么,往下学习!!!

public class DemoThreadPool02 {public static void main(String[] args) {//这里其实引用了多态的写法,ExecutorService是一个接口不能创建对象,
//所以这里的service其实是ExecutorService接口的实现类对象ThreadPoolExecutor
        ExecutorService service = Executors.newFixedThreadPool(5);//        System.out.println(service.getClass());//获取当前对象所属的类的路径class java.util.concurrent.ThreadPoolExecutor
        ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) service;FutureTask futureTask = new FutureTask(new PrintPrimeNumber());
​
        service.submit(futureTask);//执行实现Callable接口的实现类对象的线程
        service.execute(new PrintPrimeNumber02());//执行实现Runnable接口的实现类的线程
​
        service.shutdown();//关闭连接池}}/**
 * 打印100以内的质数
 */
class PrintPrimeNumber02 implements Runnable{@Override
    public void run() {
        for (int i = 2; i <= 100; i++) {boolean isFlag = true;for (int j = 2; j <= Math.sqrt(i); j++) {if (i % j == 0){
                    isFlag = false;
                    break;
                }}
            if (isFlag == true)
                System.out.println(i);
        }
    }
}/**
 * 打印100-200以内的质数
 */
class PrintPrimeNumber implements Callable{private int num = 100;@Override
    public Object call() throws Exception {
​
​
        for (int i = 100; i <= 200; i++) {boolean isFlag = true;for (int j = 2; j <= Math.sqrt(i); j++) {if (i % j == 0){
                    isFlag = false;
                    break;
                }}
            if (isFlag == true)
                System.out.println(i);
        }
        return null;
    }
}

四、实现Callable接口:

实现Callable接口有别于前两种创建线程的方式,实现Callable接口不是重写/实现run()而是实现call()方法,并且有返回值。

class Demo implements Callable {//有Object类型的返回值,如果分线程需要该线程提供值,然后继续线程时可以使用实现Callable接口
//如果不想要返回值,直接让返回值为null即可。
    @Override
    public Object call() throws Exception {
        return null;
    }
}

实现Callable接口需要结合Future接口使用,使用Future接口的唯一实现类FutureTask去接收返回值,注意此时并没有开启线程,如果开启线程的话还需要借助Thread类去,开始线程调用call()方法。

FutureTask实现类底层实现了RunnableFuture接口,而RunnableFuture接口底层继承自Runnable接口和Future接口…所以在使用new Thread类开启线程底层运用了和实现Runnable接口类似的效果。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

案例:

public class DemoCallable02 {public static void main(String[] args) {ArraySums arraySums = new ArraySums();
        FutureTask futureTask = new FutureTask(arraySums);
        //可是使用下面的方法一气呵成
//      FutureTask futureTask = new FutureTask(new ArraySums());        Thread thread = new Thread(futureTask);
        thread.start();try {
            Object sum = futureTask.get();
            System.out.println("100以内的偶数和为:" + sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
​
​
    }
}//计算100以内的偶数和
class ArraySums implements Callable {private int i = 1;
    private int sum = 0;@Override
    public Object call() throws Exception {while (true){
            if (i <= 100){if (i % 2 == 0){System.out.println(i);
                    sum += i;
                }
​
                i ++;
            }else {
                break;
            }
        }
        return sum;
    }
}

案例说明:

如果我们不使用new Thread.start(),就不会执行call()方法中的内容,也就是还没有启动线程;
使用FutureTask实现类,目的是接收call()方法的返回值…FutureTask实现类中的get()方法会获取call()方法的返回值…另外FutureTask实现类中也定了很多对接call()的方法…
如果不用接收call()方法的返回值,可以将返回值设置为null,不用使用get()方法。

实现Callable接口的好处:

Callable接口是有泛型的,可以规范用户的存储;

Callable接口中的call()方法是有返回值的,可以方便线程间的通信;
Callable接口中的call()方法是可以抛异常的,可以在后续异常进行捕获和处理。

欢迎关注微信公众号:小红的成长日记,一起学Java!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值