多线程的创建

方法一:继承Thread类


过程:
1.自定义线程类,继承Thread类
2.重写run方法
3.创建线程对象,调用start方法

package com.daiyi;

//创建线程方式一:继承Thread类,重写run方法,调用start开启线程
public class TestThread1 extends Thread{

    @Override
    public void run() {
        //run方法线程体
        for (int i = 0; i < 20; i++){
            System.out.println("这是多线程---"+i);
        }
    }

    public static void main(String[] args) {
        //main线程,主线程

        //创建线程对象
        TestThread1 testThread1 = new TestThread1();
        //调用start
        testThread1.start();

        for (int i = 0; i < 100; i++){
            System.out.println("我在学习多线程---"+i);
        }
    }
}

 

方法二:实现Runnable接口

1.定义MyRunnable类实现Runnable接口

2.实现run()方法,编写线程执行体

3.创建线程对象,调用start()方法启动线程

package com.daiyi;

//1.定义MyRunnable类实现Runnable接口
// 2.实现run()方法,编写线程执行体
// 3.创建线程对象,调用start()方法启动线程
public class TestThread3 implements Runnable{
    @Override
    public void run() {
        //run方法线程体
        for (int i = 0; i < 20; i++){
            System.out.println("这是多线程---"+i);
        }
    }

    public static void main(String[] args) {
       //创建一个Runnable接口的实现类对象
        TestThread3 testThread3 = new TestThread3();

        //创建线程对象,通过线程对象来开启我们的线程,代理
        Thread thread = new Thread(testThread3);
        thread.start();
        //或者  new Thread(testThread3).start();

        for (int i = 0; i < 100; i++){
            System.out.println("我在学习多线程---"+i);
        }
    }
}

 

方法一与方法二的对比:

继承Thread类

实现Runnable接口

子类继承Thread类具备多线程能力

启动线程:子类.start()

不建议使用:避免OOP但继承局限性

实现接口Runnable具有多线程能力

启动线程:传入目标对象+Thread对象.start()

推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用

 

方法三:实现Callable接口(了解即可)

1.定义MyCallable类实现Callable接口,包含了返回值

2.实现call()方法,编写线程执行体,call方法有返回类型

3.创建线程对象

4.创建执行服务

5.提交执行

6.获取结果

7.关闭服务

下载图片

package com.daiyi.demo2;

import com.daiyi.demo1.TestThread2;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;

//线程创建方式3,实现Callable接口
public class TestCallable implements Callable<Boolean> {
    private String url;//网络图片地址
    private String name;//保存的文件名

    //线程的构造方法
    public TestCallable(String url,String name){
        this.url = url;
        this.name = name;
    }


    //重写run方法,下载图片线程的执行体
    @Override
    public Boolean call() {
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(url,name);
        System.out.println("下载了文件名为:"+name);
        return true;
    }


    //main
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建三个下载的线程
        TestCallable t1 = new TestCallable("https://img1.baidu.com/it/u=2468362699,2612376962&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500","1.jpg");
        TestCallable t2 = new TestCallable("https://img1.baidu.com/it/u=273892741,1142580910&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500","2.jpg");
        TestCallable t3 = new TestCallable("https://img2.baidu.com/it/u=4093367817,2075246768&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=675","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();
        
        //关闭服务
        ser.shutdownNow();


    }
}


//下载器
class WebDownloader{
    //下载方法
    public void downloader(String url,String name){
        try {
            //通过FileUtils工具类的copyURLToFile方法,通过url下砸图片命名为name
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO异常,downloader方法出现问题");
        }
    }
}

 

posted @ 2023-04-20 22:44  阿鲲  阅读(40)  评论(0)    收藏  举报