仅主线程一条执行路径
多条执行路径,主线程和子线程并行交替执行。
在操作系统中运行的程序就是进程,如QQ、播放器、游戏、IDE。
一个进程可以有多个线程,如视频中同时听声音,看图像,看弹幕等。
程序是指令和数据的有序集合,其本身没有运行的含义,是一个静态的概念。
进程是执行程序的一次执行过程,它是一个动态的概念,是系统资源分配的单位。
一个进程中可以包含若干个线程,至少也有一个,线程是CPU调度和执行的单位。
真正的多线程:有多个CPU(多核),如服务器。
虚假的多线程:通过模拟获得,即在一个CPU的情况下,同一个时间点CPU只执行一个代码,但切换的速度很快,让人产生同时执行的错觉。
main函数就是主线程,其他均称子线程。
线程就是独立的执行路径
在程序运行时即使没有自己创建线程,后台也会有多个线程,如 main 函数主线程和 gc 线程。
main() 称为主线程,是系统的入口,用于执行整个程序。
在一个进程中,如果开辟了多个线程,线程的运行会由调度器 (CPU) 安排调度,调度器与操作系统紧密相关,先后顺序不能人为干预。
对同一份资源操作时会存在资源抢夺的问题,需要加入并发控制。
线程会带来额外的开销,如CPU调度时间和并发控制开销。
每个线程在自己的工作内存中交互,内存控制不当会造成数据不一致的情况。
学习函数前要会看 JDK 帮助文档
自定义线程类继承Thread类
重写 run ( ) 方法,编写线程执行体。
创建线程对象,调用 start ( ) 方法启动线程。
package com.kuang.demo; //创建线程方式一: 继承Thread类、重写run方法、调用start开启线程 public class StartThread extends Thread{ //线程入口点 @Override public void run(){ //run方法线程体 for(int i=0; i < 20; i++){ System.out.println("lisening"); } } } public static void main(String[] args){ //main主线程内创建线程对象 StartThread t = new StartThread(); //调用start方法开启线程,记住不是调用run方法!用start就会交替执行,是多线程的概念,用run就是顺序执行单线程了。 t.start(); }
线程开启过后不一定立即执行,由CPU安排调度,所以可能每次执行结果都不一样。
package com.kuang.demo; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.net.URL; //练习 Thread 实现多线程同步下载图片 public class TestThread extends Thread{ private String url; //网络图片地址 private String name; //保存的文件名 //用构造器丢入两个参数,类初始化就直接用。 public TestThread(String url, String name){ this.url = url; this.name = name; } @Override //run()方法就是下载图片线程的执行体 public void run(){ WebDownloader webDownloader = new WebDownloader(); webDownloader.downloader(url, name); System.out.println("下载的文件名为:" + name); } public static void main(String[] args){ TestThread t1 = new TestThread("http://blog.kuangstudy.com/......", "why1.jpg"); TestThread t2 = new TestThread("http://blog.kuangstudy.com/......", "why2.jpg"); TestThread t3 = new TestThread("http://blog.kuangstudy.com/......", "why3.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方法出现问题"); } } }