线程 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 方法出现问题"); } } } }