0%

多线程-Callable接口

通过实现Callable接口。

环境:IntelliJ IDEA、Java语言

步骤

  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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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。

编写测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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();
}
}

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

步骤四

创建执行服务。

1
ExecutorService ser = Executors.newFixedThreadPool(4);

步骤五

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

1
2
3
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);

步骤六

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

1
result1.get()

步骤七

关闭服务。

1
ser.shutdownNow();

测试

运行结果:

1
2
3
4
5
6
7
8
9
10
11
开始下载。。。

文件下载成功!保存路径为:/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

若图片不能正常显示,请在浏览器中打开

欢迎关注我的其它发布渠道