学习狂神视频的第一天
前言:为什么学习多线程
对于日常的软件和游戏,我们都需要处理并发的情况,比如互相同时发消息,联机游戏。
为什么要想到这些问题呢?
在此之前,我们写的程序都是一行一行执行的、顺序执行的。
例如之前的五子棋。
但是实际情况中,我们许多条件是需要同时执行的。
就像电商抢购,我一共就100件库存,但是由于一万个人想购买
所以我就需要给这些人排队。
软件也是这个道理。
一、线程的概念
在介绍线程前,我们首先知道程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念。而进程是程序的一次执行过程,它是系统资源分配的单位,是一个动态的概念。Java 虚拟机允许应用程序并发地运行多个执行线程,因此一个进程可以有多个线程。线程作为CPU调度和执行的单位,它拥有独立的执行路径。
1.在一个进程中,如果开辟了多个线程,线程的运行将由调度器安排调度,调度器与操作系统是紧密相关的,因此执行线程的先后顺序不能人为干预。真正的多线程是指有多个CPU。但是,很多多线程都是模拟出来的,即在同一个时间点,CPU只能执行一个代码,因为切换的很快,所以出现了同时执行的错觉。
2.多线程会带来额外的开销(如CPU调度时间,并发控制开销),线程越多,CPU的开销越大。
每个线程都有自己的工作内存,内存控制不当会造成数据不一致。
线程开启后不一定立即执行,由CPU调度安排。多线程的运行由调度器安排调度,先后顺序不能人为干预。
二、Thread类
1.创建thread
通过继承Thread类建立线程具体步骤:
step1:继承Thread类
step2:重写run()方法
step3:创建继承了Thread类的对象,调用start()方法启动线程
// 创建线程方式一:继承Thread类,重写run方法,调用start开启线程
public class Thread1 extends Thread{
public void run()
//run方法线程体
{
for(int i = 0;i<20;i++)
{
System.out.println("我在看代码" +i );
}
}
public static void main(String[] args)
{
Thread1 testthread1 = new Thread1();
//调用start()方法开启线程
testthread1.start();
for(int i = 0;i<20;i++)
{
System.out.println("我在学习多线程" + i);
}
}
}
2.结果
可以看到 这里并不是按照顺序执行的 而是两个线程争抢执行。
多线程下载图片
import java.io.File;
import java.io.IOException;
import java.net.URL;
import org.apache.commons.io.FileUtils;
public class Thread2 extends Thread{
private String url; // 地址
private String name; // 保存的文件名
public Thread2(String url,String name)
{
this.url = url;
this.name = name;
}
public void run()
{
WebDownLoader webDownLoader = new WebDownLoader();
webDownLoader.downloader(url, name);
System.out.println("下载了文件名为:" + name);
}
public static void main(String[] args)
{
Thread2 t1 = new Thread2("https://kuangstudy.oss-cn-beijing.aliyuncs.com/bbs/2021/04/09/kuangstudy7f75f7f2-1a87-43a1-9d7d-ab8855b6a981.png","1.jpg");
Thread2 t2 = new Thread2("https://kuangstudy.oss-cn-beijing.aliyuncs.com/bbs/2021/04/09/kuangstudy7f75f7f2-1a87-43a1-9d7d-ab8855b6a981.png","2.jpg");
Thread2 t3 = new Thread2("https://kuangstudy.oss-cn-beijing.aliyuncs.com/bbs/2021/04/09/kuangstudy7f75f7f2-1a87-43a1-9d7d-ab8855b6a981.png","3.jpg");
t1.start();
t2.start();
t3.start();
}
}
// 下载器
class WebDownLoader
{
public void downloader(String url,String name)
{
try {
FileUtils.copyURLToFile(new URL(url), new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常,downloader方法出现问题");
}
}
}
下面展示结果
我们可以看到,这也不是挨个下载完成的,而是三个同时下载。