我是靠谱客的博主 难过星月,这篇文章主要介绍java实现多线程的三种方法1、通过继承Thread实现多线程2、通过Callable接口实现多线程3、通过继承Runnable接口实现多线程,现在分享给大家,希望可以做个参考。
1、通过继承Thread实现多线程
将以实现多线程同步下载图片为例进行讲解
1.1 导入 commons-io 包
- 在项目中建立一个 lib 文件夹,将下载的
commons-io包复制进去。 - 对 lib 文件夹右键,点击
Add As Library。成功之后commons-io可以点开,如下图所示:

1.2 下载类
利用commons-io包中的FileUtils.copyURLToFile方法来下载图片
class WebDownloader {
//下载方法
public void downloader(String url, String file) {
try {
//FileUtils来自commons-io包
FileUtils.copyURLToFile(new URL(url), new File(file));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常,WebDownloader类中的downloader方法出现问题");
}
}
}
1.3 写线程类
继承Thread类,重写run()方法,并建立多个线程,调用start()开启线程。
public class TestThread2 extends Thread {
private String url; //网络图片地址
private String name; //下载保存文件名
//构造器
public TestThread2() {
}
//构造器重载
public TestThread2(String url, String name) {
this.url = url;
this.name = name;
}
//创建一个线程
@Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(this.url, this.name);
System.out.println("下载了文件:" + name);
}
public static void main(String[] args) {
TestThread2 t1 = new TestThread2("https://img1.baidu.com/it/u=2192265457,2884791613&fm=26&fmt=auto&gp=0.jpg", "2.jpg");
TestThread2 t2 = new TestThread2("https://img2.baidu.com/it/u=2102736929,2417598652&fm=26&fmt=auto&gp=0.jpg", "3.jpg");
TestThread2 t3 = new TestThread2("https://img0.baidu.com/it/u=1514002029,2035215441&fm=26&fmt=auto&gp=0.jpg", "4.jpg");
//3个线程
t1.start();
t2.start();
t3.start();
}
}
1.4 运行结果

- 我们可以看到下载顺序为:2.jpg、1.jpg、3.jpg
这与代码中的 t1.start()、t2.start()、t3.start() 的顺序不符。
这正是因为线程开启后,不一定立刻执行,是由CPU调度的。这也是本实验的重要的探究目之一。
1.4 程序汇总
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
//练习Thread,实现多线程同步下载图片
public class TestThread2 extends Thread {
private String url; //网络图片地址
private String name; //下载保存文件名
//构造器
public TestThread2() {
}
public TestThread2(String url, String name) {
this.url = url;
this.name = name;
}
//创建一个线程
@Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(this.url, this.name);
System.out.println("下载了文件:" + name);
}
public static void main(String[] args) {
TestThread2 t1 = new TestThread2("https://img1.baidu.com/it/u=2192265457,2884791613&fm=26&fmt=auto&gp=0.jpg", "2.jpg");
TestThread2 t2 = new TestThread2("https://img2.baidu.com/it/u=2102736929,2417598652&fm=26&fmt=auto&gp=0.jpg", "3.jpg");
TestThread2 t3 = new TestThread2("https://img0.baidu.com/it/u=1514002029,2035215441&fm=26&fmt=auto&gp=0.jpg", "4.jpg");
//3个线程
t1.start();
t2.start();
t3.start();
}
}
class WebDownloader {
//下载方法
public void downloader(String url, String file) {
try {
//FileUtils来自commons-io包
FileUtils.copyURLToFile(new URL(url), new File(file));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常,WebDownloader类中的downloader方法出现问题");
}
}
}
2、通过Callable接口实现多线程
- 实现Callable接口,需要返回值类型,如下返回值类型为
Boolean:
public class TestCallable implements Callable<Boolean> - 重写call方法,需要抛出异常,返回值为
Callable中的泛型。 - 创建目标对象,即new一个自己所写继承Callable接口类的对象
- 创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(3);(括号中的数字代表线程池中线程个数) - 提交执行,其中
Future的类型与Callable的返回值类型相同
Future<Boolean> result1 = ser.submit(t1); - 获取结果
boolean r1 = result1.get(); - 关闭服务
ser.shutdown();
import java.util.concurrent.*;
public class TestCallable implements Callable<Boolean> {
private String url;
private String name;
//构造器
public TestCallable() {
}
public TestCallable(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public Boolean call() throws Exception {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(this.url, this.name);
System.out.println("下载了文件名为:" + name);
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建目标对象
TestCallable t1 = new TestCallable("https://img1.baidu.com/it/u=2192265457,2884791613&fm=26&fmt=auto&gp=0.jpg", "1.jpg");
TestCallable t2 = new TestCallable("https://img2.baidu.com/it/u=2102736929,2417598652&fm=26&fmt=auto&gp=0.jpg", "2.jpg");
TestCallable t3 = new TestCallable("https://img0.baidu.com/it/u=1514002029,2035215441&fm=26&fmt=auto&gp=0.jpg", "3.jpg");
//创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(3);
//提交执行
Future<Boolean> r1 = ser.submit(t1);
Future<Boolean> r2 = ser.submit(t2);
Future<Boolean> r3 = ser.submit(t3);
//获取结果
boolean rs1 = r1.get();
boolean rs2 = r2.get();
boolean rs3 = r3.get();
System.out.println(rs1);
System.out.println(rs2);
System.out.println(rs3);
//关闭服务
ser.shutdown();
}
}
3、通过继承Runnable接口实现多线程
3.1 具体方法
继承Runnable接口,重写run()方法,执行接口需要向Thread对象丢入Runnable接口的实现类,然后调用Thread对象的start()方法。
public class TestThread4 implements Runnable {
private String url; //网络图片地址
private String name; //下载保存文件名
//构造器
public TestThread4() {
}
public TestThread4(String url, String name) {
this.url = url;
this.name = name;
}
//创建一个线程
@Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(this.url, this.name);
System.out.println("下载了文件:" + name);
}
public static void main(String[] args) {
TestThread2 t1 = new TestThread2("https://img1.baidu.com/it/u=2192265457,2884791613&fm=26&fmt=auto&gp=0.jpg", "1.jpg");
TestThread2 t2 = new TestThread2("https://img2.baidu.com/it/u=2102736929,2417598652&fm=26&fmt=auto&gp=0.jpg", "2.jpg");
TestThread2 t3 = new TestThread2("https://img0.baidu.com/it/u=1514002029,2035215441&fm=26&fmt=auto&gp=0.jpg", "3.jpg");
//3个线程
new Thread(t1).start();
new Thread(t2).start();
new Thread(t3).start();
}
}
3.2 Thread类与Runnable接口方法对比

最后
以上就是难过星月最近收集整理的关于java实现多线程的三种方法1、通过继承Thread实现多线程2、通过Callable接口实现多线程3、通过继承Runnable接口实现多线程的全部内容,更多相关java实现多线程内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复