Java多线程(二): 创建线程

三种创建方式

  1. 继承Thread类
  2. 实现Runnable接口
  3. 实现Callable接口

方法一

继承Thread类, 重写run()方法, 调用start()开启线程

  • run()

If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; otherwise, this method does nothing and returns.

  • start()

Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.

线程开启不一定立即执行, 由CPU调度执行

package com.shu.thread;

public class ThreadDemo01 extends Thread{
    @Override
    public void run() {
        // run方法线程体
        for(int i = 0; i < 200; i++){
            System.out.println("AAAAAAAAAAAAAAAAA" + i);
        }
    }

    public static void main(String[] args) {
        new ThreadDemo01().start();
//        new ThreadDemo01().run();

        for (int i = 0; i < 1000; i++) {
            System.out.println("BBBBBBBBBBBBBBBB" + i);
        }
    }
}

通过Thread下载图片

package com.shu.thread;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

public class ThreadDemo02 extends Thread{
    private String url; // 网络图片地址
    private String pathName; // 保存的文件名

    public ThreadDemo02(String url, String pathName){
        this.url = url;
        this.pathName = pathName;
    }

    @Override
    public void run() {
        WebDownLoader webDownLoader = new WebDownLoader();
        webDownLoader.downloader(url, pathName);
        System.out.println("下载了文件名为: " + pathName);
    }

    // 实现多线程同步下载图片
    public static void main(String[] args) {
        ThreadDemo02 threadDemo0201 = new ThreadDemo02("https://i.cnblogs.com/assets/adminlogo.gif", "src/com/shu/thread/adminlogo.gif");
        ThreadDemo02 threadDemo0202 = new ThreadDemo02("https://pic2.zhimg.com/80/v2-8df0e1ada7af09d3c62f2ba5ec4e4266_1440w.jpg", "src/com/shu/thread/xiyan.jpg");
        ThreadDemo02 threadDemo0203 = new ThreadDemo02("https://pic1.zhimg.com/80/v2-b3972560b6f5b7ecfac44b3ceb78d134_1440w.jpg", "src/com/shu/thread/xingkong.jpg");
        ThreadDemo02 threadDemo0204 = new ThreadDemo02("https://pic3.zhimg.com/80/v2-0a80487d102fa8f4323279779e7ee940_1440w.jpg", "src/com/shu/thread/yekong.jpg");

        threadDemo0201.start();
        threadDemo0202.start();
        threadDemo0203.start();
        threadDemo0204.start();

    }
}

// 下载器
class WebDownLoader{
    // 下载方法
    public void downloader(String url, String pathName){
        try {
            FileUtils.copyURLToFile(new URL(url), new File(pathName));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO异常, downloader方法出现问题");
        }
    }
}

方法二: 实现Runnable (因为Java单继承的局限性, 推荐使用这个方法, 方便同一个对象被多个线程使用)

  • 定义MyRunnable类实现Runnable接口
  • 实现run()方法, 编写线程执行体
  • 创建线程对象, 调用start()方法启动线程
package com.shu.thread;

public class CreateThreadByRunnable implements Runnable{
    @Override
    public void run() {
        // run方法线程体
        for(int i = 0; i < 200; i++){
            System.out.println("AAAAAAAAAAAAAAAAA" + i);
        }
    }

    public static void main(String[] args) {
        // 创建线程对象, 通过线程对象来开启我们的线程, 代理
        new Thread(new CreateThreadByRunnable()).start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("BBBBBBBBBBBBBBBB" + i);
        }
    }
}

方法三: 实现Callable接口

  1. 实现Callable接口, 需要返回值类型
  2. 重写call方法, 需要抛出异常
  3. 创建目标对象
  4. 创建执行服务: ExecutorService ser = Executors.newFieldThreadPool(1);
  5. 提交执行: Future result1 = ser.submit(t1);
  6. 获取结果: boolean r1 = result1.get();
  7. 关闭服务: ser.shutdownNow();
package com.shu.thread;

import org.apache.commons.io.FileUtils;

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

public class ThreadDemo03 implements Callable<Boolean> {
    private String url; // 网络图片地址
    private String pathName; // 保存的文件名

    public ThreadDemo03(String url, String pathName){
        this.url = url;
        this.pathName = pathName;
    }


    @Override
    public Boolean call() throws Exception {
        WebDownLoader webDownLoader = new WebDownLoader();
        webDownLoader.downloader(url, pathName);
        System.out.println("下载了文件名为: " + pathName);
        return true;
    }

    // 实现多线程同步下载图片
    public static void main(String[] args) {
        ThreadDemo03 threadDemo0301 = new ThreadDemo03("https://i.cnblogs.com/assets/adminlogo.gif", "src/com/shu/thread/adminlogo.gif");
        ThreadDemo03 threadDemo0302 = new ThreadDemo03("https://pic2.zhimg.com/80/v2-8df0e1ada7af09d3c62f2ba5ec4e4266_1440w.jpg", "src/com/shu/thread/xiyan.jpg");
        ThreadDemo03 threadDemo0303 = new ThreadDemo03("https://pic1.zhimg.com/80/v2-b3972560b6f5b7ecfac44b3ceb78d134_1440w.jpg", "src/com/shu/thread/xingkong.jpg");
        ThreadDemo03 threadDemo0304 = new ThreadDemo03("https://pic3.zhimg.com/80/v2-0a80487d102fa8f4323279779e7ee940_1440w.jpg", "src/com/shu/thread/yekong.jpg");

        ExecutorService executorService = Executors.newFixedThreadPool(4);

        Future<Boolean> result1 = executorService.submit(threadDemo0301);
        Future<Boolean> result2 = executorService.submit(threadDemo0302);
        Future<Boolean> result3 = executorService.submit(threadDemo0303);
        Future<Boolean> result4 = executorService.submit(threadDemo0304);

        try {
            boolean r1 = result1.get();
            boolean r2 = result2.get();
            boolean r3 = result3.get();
            boolean r4 = result4.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        executorService.shutdownNow();

    }
}

posted @ 2020-05-23 19:58  Archer_Shu  阅读(153)  评论(0编辑  收藏  举报