我是靠谱客的博主 难过星月,最近开发中收集的这篇文章主要介绍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实现多线程的三种方法1、通过继承Thread实现多线程2、通过Callable接口实现多线程3、通过继承Runnable接口实现多线程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复