多线程-Callable接口

通过实现Callable接口实现多线程。
环境:IntelliJ IDEA、JDK1.8


步骤

  1. 自定义类,实现Callable接口,需要返回值(call方法)
  2. 实现call()方法,编写线程执行体(可以抛出异常)
  3. 创建目标对象,假设为t1
  4. 创建执行服务ExecutorService ser = Executors.newFixedThreadPool(int 线程个数);
  5. 提交执行结果Future<t1返回值类型> result1 = ser.submit(目标对象t1);(t1返回值类型在前边定义类时定义)
  6. 获取结果t1返回值类型 r1 = result1.get(); (可以抛出异常)
  7. 关闭服务ser.shutdownNow();

代码演示

步骤一

自定义类,实现Callable接口,需要返回值(call方法)。

步骤二

实现call()方法,编写线程执行体(可以抛出异常)

对Thread类中的扩展进行修改,修改成实现Callable接口的方式。类命名为webDownloader2。因为实现Callable接口可以定义返回值,所以这里把downloader方法和run方法合并为call()方法。把System.out.printf()改成return

class webDownloader2 implements Callable {
    private String url;//网络资源URL
    private String local;//下载的文件,保存路径
    private String name;//下载到本地后的文件名
    public webDownloader2(String url,String local,String name){
        this.url = url;
        this.name = name;
        this.local = local;
    }
    public webDownloader2(String url,String local){
        this.local = local;
        this.url = url;
        this.name = url.substring(url.lastIndexOf("/")+1);//若不指定文件名,则根据url进行命名,包括后缀一共不得超过20个字符
        this.name = this.name.length()>20?this.name.substring(this.name.length()-20):this.name;
    }
    @Override
    public String call() {//线程
        String localName = this.local+this.name;
        try {
            File file = new File(localName);
            while (file.exists()){//判断是否有重名的文件
                StringBuffer newName = new StringBuffer(this.name);
                newName.insert(newName.lastIndexOf("."),"0");//文件名后边加个0
                this.name = newName.toString();//更新文件名
                this.name = this.name.length()>20?this.name.substring(this.name.length()-20):this.name;
                localName=this.local + this.name;//更新下载路径(包括文件名)localName
                file = new File(localName);//更新file,下一次循环重新判断是否存在重名的文件
            }
            FileUtils.copyURLToFile(new URL(this.url),new File(localName));//调用Commons io包的类,进行文件下载
            return "\n文件下载成功!保存路径为:"+localName;
        } catch (IOException e) {
            e.printStackTrace();
            return "\n文件下载失败!!!";
        }
    }
}

步骤三

创建目标对象。下边的t1-t4。

编写测试类:

public class TestCallable {
    public static void main(String[] args) {
        String url1 = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1599476670887&di=c6b212a71544515388465aa47ad81dd6&imgtype=0&src=http%3A%2F%2Fimg.mp.sohu.com%2Fq_70%2Cc_zoom%2Cw_640%2Fupload%2F20170801%2F78c2a43c2204429dbe7b864f71658f88_th.jpg";
        String url2 = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1599476817781&di=b5c0bb5b838466f59a47c87a67727168&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2Fattachments2%2F201311%2F07%2F1336364xq9592q8kpx498q.jpg";
        String url3 = "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=176574130,4070812636&fm=26&gp=0.jpg";
        String url4 = "https://mirrors.tuna.tsinghua.edu.cn/apache//commons/io/binaries/commons-io-2.8.0-bin.tar.gz";
        String local = "/Users/qingshuaidebaoluo/Desktop/";
        webDownloader2 t1 = new webDownloader2(url1,local);
        webDownloader2 t2 = new webDownloader2(url2,local);
        webDownloader2 t3 = new webDownloader2(url3,local,"小黄人.jpg");
        webDownloader2 t4 = new webDownloader2(url4,local,"commons-io-2.8.0-bin.tar.gz");

        //创建执行服务
        ExecutorService ser = Executors.newFixedThreadPool(4);
        //提交执行
        Future<String> result1 = ser.submit(t1);
        Future<String> result2 = ser.submit(t2);
        Future<String> result3 = ser.submit(t3);
        Future<String> result4 = ser.submit(t4);
        System.out.printf("开始下载。。。\n");
        //获取结果
        try {//try-catch包裹或抛出异常
            System.out.println(result1.get());
            System.out.println(result2.get());
            System.out.println(result3.get());
            System.out.println(result4.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //关闭服务
        ser.shutdownNow();
    }
}

下边步骤中的示例代码都是在该测试类中摘取出来的。

步骤四

创建执行服务。

 ExecutorService ser = Executors.newFixedThreadPool(4);

步骤五

提交执行结果。实现Callable接口的类webDownloader2中的call()方法的返回值类型为String。

 Future<String> result1 = ser.submit(t1);
 Future<String> result2 = ser.submit(t2);
 Future<String> result3 = ser.submit(t3);
 Future<String> result4 = ser.submit(t4);

步骤六

获取结果。get()方法,获取call()方法的返回值。

result1.get()

步骤七

关闭服务。

ser.shutdownNow();

测试

运行结果:

开始下载。。。

文件下载成功!保存路径为:/Users/qingshuaidebaoluo/Desktop/b864f71658f88_th.jpg

文件下载成功!保存路径为:/Users/qingshuaidebaoluo/Desktop/4xq9592q8kpx498q.jpg

文件下载成功!保存路径为:/Users/qingshuaidebaoluo/Desktop/小黄人.jpg

文件下载成功!保存路径为:/Users/qingshuaidebaoluo/Desktop/commons-io-2.8.0-bin.tar.gz

Process finished with exit code 0


学习自B站遇见狂神说
相关博客:多线程-汇总

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值