线程 Thread [θred]

  • 普通方法与多线程

    图片说明

1.程序:

程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念

2.进程:

在操作系统中运行的程序就是进程,比如QQ,播放器,游戏,IDE等等

进程是执行程序的一次执行过程,它是一个动态的概念,是系统资源分配的单位

3.线程:

进程可以有多个线程,如视频中同时听声音,看图像,看弹幕

通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没有存在的意义,线程是CPU调度和执行的的单位

注意

很多多线程是模拟出来的,真正的多线程是指有多个cpu,即多核,如服务器

如果是模拟出来的多线程,即在一个cpu的情况下,在同一个时间点,cpu只能执行一个代码,因为切换的很快,所以就有同时执行的错局

核心

  • 线程就是独立的执行路径

  • 在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程;

  • main(称之为主线程,为系统的入口,用于执行整个程序;

  • 在一个进程中,如果开辟了多个线程,线程的运行由调度器(cpu)安排调度,调度器是与操作系统紧密相关的,先后顺序是不能人为的干预的

  • 对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制

  • 线程会带来额外的开销,如cpu调度时间,并发控制开销。

  • 每个线程在自己的工作内存交互,内存控制不当会造成数据不一致

线程创建

三种方式


1.继承Thread类


开启多线程   main线程可以和run方法线程同时跑

小实现

package com.vis_yang.thread;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
//练习Thread,实现多线程同步下载图片
public class ThreadDemo02 extends Thread {
//属性
private String url;//网络图片地址
private String name;//保存的文件名
//写有参构造引入参数
public ThreadDemo02(String url,String name){
this.url=url;
this.name=name;
}
//下载图片的线程执行体
@Override
public void run() {
WebPhotoDownloader webPhotoDownloader = new WebPhotoDownloader();
try {
webPhotoDownloader.downloader(url,name);
System.out.println("下载了文件名为:"+name);
} catch (IOException e) {
e.printStackTrace();
System.out.println("调用downloader失败");
}
}
public static void main(String[] args) {
ThreadDemo02 photo1 = new ThreadDemo02("[https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa0.att.hudong.com%2F30%2F29%2F01300000201438121627296084016.jpg&refer=http%3A%2F%2Fa0.att.hudong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1616905620&t=b36b1bd5e1b084e9088818b9bdb27176"](https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa0.att.hudong.com%2F30%2F29%2F01300000201438121627296084016.jpg&refer=http%3A%2F%2Fa0.att.hudong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1616905620&t=b36b1bd5e1b084e9088818b9bdb27176"),
"photo1.jpg");
ThreadDemo02 photo2 = new ThreadDemo02("[https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa0.att.hudong.com%2F30%2F29%2F01300000201438121627296084016.jpg&refer=http%3A%2F%2Fa0.att.hudong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1616905620&t=b36b1bd5e1b084e9088818b9bdb27176"](https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa0.att.hudong.com%2F30%2F29%2F01300000201438121627296084016.jpg&refer=http%3A%2F%2Fa0.att.hudong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1616905620&t=b36b1bd5e1b084e9088818b9bdb27176"),
"photo2.jpg");
ThreadDemo02 photo3 = new ThreadDemo02("[https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa0.att.hudong.com%2F30%2F29%2F01300000201438121627296084016.jpg&refer=http%3A%2F%2Fa0.att.hudong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1616905620&t=b36b1bd5e1b084e9088818b9bdb27176"](https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa0.att.hudong.com%2F30%2F29%2F01300000201438121627296084016.jpg&refer=http%3A%2F%2Fa0.att.hudong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1616905620&t=b36b1bd5e1b084e9088818b9bdb27176"),
"photo3.jpg");
photo1.start();
photo2.start();
photo3.start();
}
}
//下载器
class WebPhotoDownloader{
//下载方法
public void downloader(String url,String name) throws IOException {
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("downloader 方法出现问题");
}
}
}

成功


2.实现runable接口

package com.vis_yang.thread;

import org.apache.commons.io.FileUtils;

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

//练习Thread,实现多线程同步下载图片
public class ThreadDemo02 implements Runnable {
    //属性
    private String url;//网络图片地址
    private String name;//保存的文件名

    //写有参构造引入参数
    public ThreadDemo02(String url, String name) {
        this.url = url;
        this.name = name;
    }

    //下载图片的线程执行体
    @Override
    public void run() {
        WebPhotoDownloader webPhotoDownloader = new WebPhotoDownloader();
        try {
            webPhotoDownloader.downloader(url, name);
            System.out.println("下载了文件名为:" + name);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("调用downloader失败");
        }

    }

    public static void main(String[] args) {
        ThreadDemo02 photo1 = new ThreadDemo02("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa0.att.hudong.com%2F30%2F29%2F01300000201438121627296084016.jpg&refer=http%3A%2F%2Fa0.att.hudong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1616905620&t=b36b1bd5e1b084e9088818b9bdb27176",
                "photo1.jpg");
        ThreadDemo02 photo2 = new ThreadDemo02("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa0.att.hudong.com%2F30%2F29%2F01300000201438121627296084016.jpg&refer=http%3A%2F%2Fa0.att.hudong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1616905620&t=b36b1bd5e1b084e9088818b9bdb27176",
                "photo2.jpg");
        ThreadDemo02 photo3 = new ThreadDemo02("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fa0.att.hudong.com%2F30%2F29%2F01300000201438121627296084016.jpg&refer=http%3A%2F%2Fa0.att.hudong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1616905620&t=b36b1bd5e1b084e9088818b9bdb27176",
                "photo3.jpg");
        new Thread(photo1).start();
        new Thread(photo2).start();
        new Thread(photo3).start();
    }

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


        }
    }
}

运行结果


对比小结