多线程
1、进程与线程的概念
1.1、进程是什么?
进程是在操作系统上体现的,进程就是应用程序,例如:QQ、微信、王者荣耀,只要是应用程序并且打开了就是一个进程。
1.程序的概念:
程序是一个静态的概念,代表的是系统中的应用程序的启动程序(exe等结尾的可执行文件)一旦执行程序系统就会生成一个进程。
2.进程的概念:
执行中的程序就是进程,此进程是一个动态的概念–>进程中会有执行内容(运行状态会有交互)并且赋予一定的独立功能电脑中进程是单个还是多个?
1.电脑中的进程是多个–>多进程
3.多进程的概念:
多进程就是在电脑的运行状态下,可以打开多个应用程序开启多个进程,进程之间不会有相互干扰,并且可以同时运行,进程的运行要看的是CPU的核心数–>一个核心代表你可以开启一个进程,所有的进程都会抢占CPU的执行权–>所以软件程序开的越多越消耗CPU的资源
1.2、线程是什么?
线程的概念:在应用程序中体现,并且应用程序(进程)想要执行就必须有一个线程(一般这个线程叫做主线程),线程的体现在应用程序运行。
比如:打开QQ时在一个聊天窗口那QQ会不会继续接收其他信息?–>如果QQ打开一个聊天窗口则代表开启了一个线程
1.单线程:一个应用程序中只有一个线程,也就是在执行时不能同时执行其他任务,只能等待第一个任务结束才能继续
2.多线程:在一个应用程序中可以执行多个任务
1.3、Java中谁是线程谁是进程?
Java运行是使用JRE–>JVM虚拟机中运行–JVM虚拟机是进程–>JVM虚拟机是多线程的,所以Java虚拟机执行时会出现各种的溢出(执行超载了),我们所写所有的程序是线程
JVM虚拟机是进程,我们写的可执行代码是线程
1.4、并发和并行的概念以及区别
1.4.1、并发是什么?
并发是指同一时刻只能一条指令执行,但是多个进程/线程在执行时使用轮询方式快速切换执行,使得宏观上显示的是多个进程/线程同时执行,但是在微观上则不是同时执行,而是交替执行。
1.4.2、并行是什么?
并行是指同一时刻可以执行多条指令,在宏观意义上是同时执行,同样在微观意义上也是同时执行
1.4.3、并发和并行的区别
1.并发:同时刻只能执行一条指令
2.并行:同时刻可以执行多条指令
- 注: 在使用多线程时,一定要明白什么是
并发什么是并行,并且这俩不能搞混–>什么是并发编程什么是并行编程
1.5、并发编程和并行编程的概念
1.在CPU执行繁忙时资源不足时,则这时开启多进程代表就是并发,如果程序开启较少时CPU可以实现意义上的并行执行
2.在单核CPU中执行多个程序时是由操作系统切换执行
3.在多核CPU中执行多个程序时是可以并行执行多个程序
2、Java中线程创建的几种方式(掌握)
Java中创建线程分为三种方式,并且三种方式有异同,最终其中方式相同,功能以及实现会有所不同
2.1、Java中线程类概述
Java创建多线程使用
Thread类,其中Thread是线程的启动与实现方式,并且定义了一些静态方法供开发人员使用
Thread类是直接实现于Runnable接口,Runnable接口是线程祖先
2.1.1、Thread类的构造方法
|
2.1.2、Thread类的常用方法
1.public void run() : 线程执行的方法–>线程中需要写的逻辑代码,并且不能调用此run方法,run方法是由虚拟机调用执行。
2.public synchronized void start(): 线程启动方法–>启动线程并自动执行run方法,使该线程开始执行;Java虚拟机调用该线程的run方法。
2.1.3、Thread类的静态常量
public final static int MIN_PRIORITY = 1;:设置线程最低优先级public final static int NORM_PRIORITY = 5;:设置线程默认优先级public final static int MAX_PRIORITY = 10;:设置线程最高优先级
2.1.4、线程的常用设置获取方法
public long getId():获取当前执行的线程idpublic final String getName():获取当前执行的线程名称public final int getPriority():获取当前执行的线程优先级public State getState():获取当前执行的线程状态public final ThreadGroup getThreadGroup():获取当前执行的线程分组public final void setDaemon(boolean on):是否开启守护线程public final synchronized void setName(String name):设置线程的名称public final void setPriority(int newPriority):设置线程优先级public static native Thread currentThread():获取当前线程–>获取非继承Thread类的线程
2.2、第一种:继承Thread类
2.2.1、创建多线程的步骤
1.创建一个类,继承Thread类
2.实现Thread类中run方法->run方法是多线程的执行体(线程执行的逻辑代码)
3.创建测试类,并继承了Thread类的类对象
4.调用ctart方法启动线程
2.2.2、创建多线程的具体代码
1.创建自定义类继承Thread类
public class MyThread extends Thread{ |
2.创建测试方法并创建线程启动
public class ThreadDemo { |
2.3、第二种:实现Runnable接口重写run方法,以及使用内部类创建Runnable接口
2.3.1、实现Runnable步骤
1.创建线程类,并实现Runnable
2.重写run方法并编写逻辑代码
3.创建测试类,创建实现Runnable接口的类
4.创建Thread,并将线程类做参数传入
5.启动线程测试
2.3.2、实现Runnable创建多线程具体代码
1.线程类实现Runnable接口
public class MyThread implements Runnable{ |
2.线程测试类
public class ThreadDemo { |
2.4、第三种:实现Callable接口创建线程
2.4.1、实现Callable创建线程步骤
第三种方式与前两不同,这里没有run方法,而是使用call方法去实现线程的逻辑代码,并且可以拥有返回值,但是接收返回值时会造成线程的阻塞(暂停等待接收数据),同样不能通过同一个FutureTask对象创建两个多线程
创建方式:
1.创建线程类实现Callable接口,并实现call方法
2.通过FutureTask类创建线程–>传入Callable的实现类
3.创建Thread线程对象,并将FutureTask对象传入当做参数
4.启动线程
5.接收线程返回值
2.4.2、实现Callable创建线程代码案例
1.创建线程类实现Callable接口
//实现Callable接口并指定泛型类型-->泛型类型是Value,并且是多线程的返回值 |
2.创建测试类启动线程
import java.util.concurrent.FutureTask; |
2.5、三种创建线程的优缺点与区别以及常用的是哪个
2.5.1、继承Thread类的优缺点
1.优点:继承后直接可以启动线程
2.缺点:Java是单继承的语言一旦继承了则无法继承其他的类的.造成我们的可扩展性非常低并且没有返回值
2.5.2、实现Runnable接口的优缺点
1.优点:解决了单继承的扩展性低缺点
2.缺点:没有返回值需要单独创建Thread线程类启动
3.使用非常简单的方式实现多线程
2.5.3、实现Callable接口创建FutureTask对象的优缺点
1.优点:带有返回值并且也是通过接口实现方式创建
2.缺点:使用麻烦并且接收返回值会造成程序阻塞(暂停)并且一个FutureTask对象只能启动一个线程
2.6.多线程注意事项
线程创建后不允许重复启动(不允许在同一时间启动两次)
以及run方法是由JVM虚拟机负责调用,如果我们自己调用则无法实现多线程的程序
start方法是启动线程并由JVM虚拟机负贡调用run方法实现多线程
多线程调用时是非常严谨的,一定不能出错,否则会影响程序的执行