通过实现Callable接口创建多线程

Callable接口创建:

1,实现Callable接口,需要返回值类型

2,重写call方法,需要抛出异常

3,创建目标对象

4,创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(3);

5,执行提交:Future<Boolean> f1 = ser.submit(t1);

6,获取结果:boolean r1 = f1.get();

7,关闭服务:ser.shutdownNow();

案例:

package com.Thread;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;

//实现Callable接口创建多线程
public class CallableTest implements Callable {
    private String name; //保存的文件名
    private String url; //网图地址

    public CallableTest(String url, String name) {
        this.url = url;
        this.name = name;
    }

    //重写run方法,下载图片的执行体
    @Override
    public Object call() throws Exception {
        WebDownLoader2 webDownLoader = new WebDownLoader2();
        webDownLoader.downLoader(url, name);
        System.out.println("下载了文件名为:" + name);
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CallableTest t1 = new CallableTest("https://images.cnblogs.com/cnblogs_com/blogs/697817/galleries/2011482/o_2108131222251628857175898.png", "1.png");
        CallableTest t2 = new CallableTest("https://images.cnblogs.com/cnblogs_com/blogs/697817/galleries/2011482/o_2108131222491628857044088.png", "2.png");
        CallableTest t3 = new CallableTest("https://images.cnblogs.com/cnblogs_com/blogs/697817/galleries/2011482/o_2108131222251628857175898.png", "3.png");

        //创建执行服务
        ExecutorService ser = Executors.newFixedThreadPool(3);

        //提交执行
        Future<Boolean> f1 = ser.submit(t1);
        Future<Boolean> f2 = ser.submit(t2);
        Future<Boolean> f3 = ser.submit(t3);

        //获取结果
        boolean r1 = f1.get();
        boolean r2 = f2.get();
        boolean r3 = f3.get();

        //关闭服务
        ser.shutdownNow();
    }
}

//下载器
class WebDownLoader2{
    //下载方法
    public void downLoader(String url, String name) {
        try {
            FileUtils.copyURLToFile(new URL(url), new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO异常,downLoader方法出现问题");
        }
    }
}
/*
结果:
    下载了文件名为:2.png
    下载了文件名为:1.png
    下载了文件名为:3.png
 */

Callable的好处:

1,可以定义返回值

2,可以抛出异常

三种方式的区别

1,采用Thread方式实现的线程不能继承其他父类,采用Runnable和Callable接口的可以继承其他父类,但是编程上采用Thread的方式可以直接使用getName()方法,而采用Runnable和Callable接口的方式需要先获取Thread.currentThread();

2,采用Runnable和Callable的方式,可以多个线程公用一个Target对象,而采用Thread的方式不能,所以非常适合多个相同线程来处理同一份资源的情况

3,如果需要线程有返回值的需要使用Callable的方式。

通过实现Callable接口创建多线程

上一篇:数组练习(三):用两个栈实现队列


下一篇:深入理解java虚拟机-运行时数据区