2.41 高并发之线程和进程
一、多线程
1、1 线程与进程区别
进程:每个正在系统上运行的程序都是一个进程。每个进程包含一到多个线程。
线程:线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行。
总结:进程是所有线程的集合,每一个线程是进程中的一条执行路径。多线程的好处是可以提高程序的效率。
一个应用系统可以多个进程:进程中一定有一个主线程(JAVA中Main函数)。线程是一个进程执行顺序,流程,路径,并且每个线程不影响。
1、2 生活中实例:
迅雷种子多个下载,买票系统,应用系统,Ajax异步上传。
1、3 实现多线程的方式
同步执行:单线程(同一时刻只能执行一个方法,时间相加)
异步执行:多线程(同一时刻同时执行多个方法,不相互影响,时间随最后执行完时间结束)
实现Runnable接口比继承Thread类好,因为接口可以多继承。
开始执行线程 开启线程不是调用run方法,而是start方法
创建方法: 1、第一种继承Thread类 重写run方法、范例代码:注意 开启线程不是调用run方法,而是start方法
package com.lele.JavaAll1203Test; /** * @author LIULE * @version v0.1 * @classDesc 创建多线程例子(重写Thread的run方法) */ class CreateThrea extends Thread{ public void run(){ for( int i = 0;i<=200;i++){ System.out.println("i的值为"+i); } } } public class Test01Threath { public static void main(String[]args){ System.out.println("多线程createThread开始"); CreateThrea t = new CreateThrea(); System.out.println("开始执行多线程"); t.start(); for( int i = 0;i<=200;i++){ System.out.println("MAIN"+i); } System.out.println("多线程createThread结束"); } }
2、实现Runnable接口,重写run方法,代码范例
/** * @author LIULE * @version v0.1 * @classDesc 创建多线程例子(实现Runnable接口) */ public class Test02Runnable { public static void main(String[]args){ System.out.println("创建一个多线程---"); creatRunnable c = new creatRunnable(); System.out.println("多线程开始调用---"); Thread thread = new Thread(c); thread.start(); for(int i = 0 ; i <= 200 ;i++ ){ System.out.println("i的主方法的值为"+i); } System.out.println("多线程调用结束--"); } } class creatRunnable implements Runnable{ @Override public void run(){ for(int i = 0 ; i <= 200 ;i++ ){ System.out.println("i的子线程值为"+i); } } }
3、使用匿名内部类
public class Test03InNoname { public static void main(String[]args){ System.out.println("多线程开始"); Thread thread = new Thread(new Runnable() { @Override public void run() { for ( int i = 0; i < 20;i++){ System.out.println("内部子线程i"+i); } } }); thread.start(); for ( int i = 0; i < 20;i++){ System.out.println("内部主线程i"+i); } } }
线程常用API的方法:
start()启动线程
currentThread()获取当前线程对象
getID()获取当前线程ID Thread-编号 该编号从0开始
getName()获取当前线程名称
sleep(long mill)休眠线程
Stop()停止线程,(不安全,已不使用)
二、守护线程
Java中有两种线程,一种是用户线程(非守护线程,用户线程是指用户自定义创建的线程,主线程停止,用户线程不会停止)
另一种是守护线程(和主线程一起销毁GC回收线程)。守护线程当进程不存在或主线程停止,守护线程也会被停止。
使用setDaemon(true)方法设置为守护线程
三、多线程状态
线程从创建、运行到结束总是处于下面五个状态之一:新建状态(ew Thread(r))、就绪状态(start()方法)、运行状态(真正开始执行run()方法)、
阻塞状态 线程运行过程中,可能由于各种原因进入阻塞状态:
1>线程通过调用sleep方法进入睡眠状态;
2>线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
3>线程试图得到一个锁,而该锁正被其他线程持有;
4>线程在等待某个触发条件;
死亡状态,需要使用isAlive方法
1) run方法正常退出而自然死亡,
2) 一个未捕获的异常终止了run方法而使线程猝死。
四、JOIN方法和Yield方法
1.join作用是让其他线程变为等待,t1.join();// 让其他线程变为等待,直到当前t1线程执行完毕,才释放。
thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。join方法写在相应的下一个执行的方法中。
2.Thread.yield()方法的作用:暂停当前正在执行的线程,并执行其他线程。(可能没有效果)
yield()让当前正在运行的线程回到可运行状态,以允许具有相同优先级的其他线程获得运行的机会。因此,使用yield()的目的是让具有相同优先级的线程之间能够适当的轮换执行。但是,实际中无法保证yield()达到让步的目的,因为,让步的线程可能被线程调度程序再次选中。
结论:大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。
五、面试题
1.进程与线程的区别?
答:进程是所有线程的集合,每一个线程是进程中的一条执行路径,线程只是一条执行路径。
2.为什么要用多线程?
答:提高程序效率
3.多线程创建方式?
答:继承Thread或Runnable 接口。
4.是继承Thread类好还是实现Runnable接口好?
答:Runnable接口好,因为实现了接口还可以继续继承。继承Thread类不能再继承。
5.你在哪里用到了多线程?
答:主要能体现到多线程提高程序效率。
举例:分批发送短信、迅雷多线程下载等。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· DeepSeek本地性能调优
· 一文掌握DeepSeek本地部署+Page Assist浏览器插件+C#接口调用+局域网访问!全攻略