我是靠谱客的博主 难过星月,最近开发中收集的这篇文章主要介绍java实现多线程的三种方法1、通过继承Thread实现多线程2、通过Callable接口实现多线程3、通过继承Runnable接口实现多线程,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1、通过继承Thread实现多线程

将以实现多线程同步下载图片为例进行讲解

1.1 导入 commons-io 包

  1. 在项目中建立一个 lib 文件夹,将下载的commons-io包复制进去。
  2. 对 lib 文件夹右键,点击Add As Library。成功之后commons-io可以点开,如下图所示:
    Add As Library

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接口方法对比

Thread类与Runnable接口方法对比

最后

以上就是难过星月为你收集整理的java实现多线程的三种方法1、通过继承Thread实现多线程2、通过Callable接口实现多线程3、通过继承Runnable接口实现多线程的全部内容,希望文章能够帮你解决java实现多线程的三种方法1、通过继承Thread实现多线程2、通过Callable接口实现多线程3、通过继承Runnable接口实现多线程所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(73)

评论列表共有 0 条评论

立即
投稿
返回
顶部