Java基础——线程的基本概念

线程基础

进程与线程

进程

简介:一个正在进行的程序

从内存的角度看,当程序运行时,系统会为其分配一定的运行空间(运行内存上),这片空间就是进程

线程

简介:代码的一条执行路径

1、Java程序在运行时自带一条线程,这条线程称为主线程(main线程)
2、一个进程中可以有多个线程
3、从宏观上考虑多个线程是同时执行的,但从微观上考虑,多个线程在抢夺CPU执行权,谁抢夺谁执行一句代码,然后重新抢夺,所以微观考虑他们是交替执行的,因为抢夺Cpu执行权的速度很快,所以说宏观上是同时执行的。
4、除在主线程外其他线程都称为子线程

进程与线程的关系

1、一个进程可以有多个线程
2、一个进程至少有一个线程,如果一个线程都没有,那么该进程执行结束,进程将被销毁
3、进程间不能共享临时数据,多个线程之间可以共享临时数据
4、本质上进程是一个程序的运行空间,线程是代码的一条执行路径

线程组成

1、CPU时间片:抢夺到CPU执行权后,允许执行的时长
2、运行数据
	1、堆:多个线程之间共享,存储的是对象的内存
	2、栈:每个线程拥有独立的栈,局部变量,调用的方法
3、线程的逻辑

线程的创建方式

方案一:创建Thread的子类对象
方式一:
	1、找一个类继承于Thread
	2、重写run方法
	3、创建该类对象
语法:
	//步骤一:创建一个类继承于Thread
	访问量权限修饰符 class 类名 extends Thread{
		//步骤二:重写run方法
		public void run(){
			//线程启动后执行的代码
		}
	}
	//步骤三:创建该类的对象
	类名 对象名 = new 类名();
	
方式二:
	1、创建一个继承于Thread的匿名内部类对象
	2、重写run方法
语法:
	Thread 对象名 = new Thread(){
		public void run(){
			//线程启动后执行的代码
		}
	}
方案二:将线程执行的任务(Runnable)与线程对象(Thread)拆分
方式一:
	1、找一个类实现Runnable接口
	2、重写run方法
	3、创建Thread类对象并传入实现Runnable接口的子类对象
语法:
	//步骤一:创建类实现Runnable接口
	访问量权限修饰符 class 类名 implements Runnable{
		//步骤二:重写run方法
		public void run(){
			//线程启动后执行的代码
		}
	}
	//步骤三:创建该类的对象
	类名 对象名 = new 类名();
	//步骤四:在创建Thread对象时传入该类对象
	Thread thread = new Thread(对象名);
	
	可以合并步骤三与步骤四,合并效果如下:
	Thread thread = new Thread(new 类名());
	
方式二:
	1、创建Thread类对象
	2、在其实参中传入实现了Runnable接口的匿名内部类对象,重写run方法
语法:
	Thread thread = new Thread(new Runnable(){
		public void run(){
			//线程启动后执行的代码
		}
	});
	
	
建议使用方案2:
	类只能单继承,但是接口可以多实现

线程的启动

语法:
	线程对象.start();
注意:
	使用线程对象调用run方法没有开启执行路径,所以不算是一个线程

线程的消亡

线程中run方式执行完毕后,线程就等待被gc回收
注意:线程被启动后只能等待run方法执行结束,才能结束

线程的名称

设置名称:
	线程对象.setName(线程名称);
	注意:在线程启动前设置
获取名称:
	String 变量名 = 线程对象.getName();

获取当前线程

语法:
	Thread 线程对象 = Thread.currentThread();

线程的休眠

语法:
	Thread.sleep(休眠时间单位毫秒);
	
注意:线程在休眠的时候,不参与抢夺CPU执行权,在线程中使用
作用:让该线程阻塞一会,阻塞期间不抢夺CPU执行权

线程的合并

语法:
	线程对象A.join();

作用:在A线程中使用B线程对象调用join方法,就是将B线程未执行完的任何合并到A线程中,那么当B合并到A中后,先执行完B中剩余的任务,再执行A中剩余的任务

线程的礼让

语法:
	线程对象.yield();

注意:当线程获取到CPU执行权后,释放CPU执行权,再次参与抢夺

线程的优先级

作用:增大或减小线程获取到CPU执行权的概率

语法:
	线程对象.setPriority(优先级);
	
注意:
	1、需要在线程启动前设置
	2、优先级取值范围:1~10

守护线程

又名:后台线程
一般线程默认为前台线程

注意:一个进程中所有前台线程执行完毕后,进程也将被销毁,当进程销毁时,所有守护线程也将被销毁

语法:
	线程对象.setDaemon(true/false);
注意:线程启动前设置
名词
主线程:程序自带的线程
子线程:除了主线程以外的其他线程

守护线程:设置setDaemon(true/false)的线程
前台线程:没有设置setDaemon(true/false)的线程
后台线程:就是守护线程

线程的状态

初始状态:New
	线程对象没有调用start方法之前
就绪状态:Ready
	线程可以抢夺CPU执行权
运行状态:Running
	线程获取到CPU执行权,正在执行代码
终止状态:Terminated
	线程执行完run方法中的所有代码后
等待状态:Waiting
	有限期等待:Time Waiting
		如:线程调用休息方法
	无限期等待:Waiting
		如:线程调用join方法
### Java线程基本概念 #### 什么是多线程? 在Java中,多线程是指一个程序能够同时执行多个任务。每个任务被称为一个线程线程是进程中可独立调度的最小单位,在同一时间内可以并行处理多项工作[^1]。 #### 创建线程的方法 有两种主要方式用于创建新的线程: - **继承`Thread`类** 这种方法涉及定义一个新的类来扩展`java.lang.Thread`,重写其`run()`方法以包含要在线程内执行的操作逻辑。之后实例化该自定义线程对象并通过调用它的`start()`启动它。 - **实现`Runnable`接口** 更推荐的做法是从现有类外部提供实现了`Runnable`接口的对象给标准的`Thread`构造函数。这样做不仅绕过了单一继承带来的限制,还允许更方便地共享资源或状态信息[^2]。 ```java // 使用Runnable接口的例子 public class MyTask implements Runnable { @Override public void run() { System.out.println("My task is running."); } public static void main(String[] args) { Thread thread = new Thread(new MyTask()); thread.start(); } } ``` 对于更加复杂的场景,还可以考虑使用`Callable<V>`接口配合`Future<T>`机制获取返回结果以及支持异常传播等功能。 #### 线程的状态转换 线程在其生命周期中有几种不同的状态:新建(New),就绪(Runnable),运行(Running),阻塞(Blocked),等待(Waiting),计时等待(Timed Waiting),终止(Terminated)[^3]。这些状态反映了线程当前所处的位置及其活动状况。 #### 同步与锁机制 由于多个线程可能访问相同的内存区域,因此同步成为必要措施之一,用来防止竞争条件的发生。可以通过`synchronized`关键字或者显式的锁定原语如ReentrantLock来进行控制。 #### 守护线程 vs 用户线程 Java中的线程分为两种类型——用户线程和守护线程。前者通常代表应用程序的主要业务流程;后者则负责辅助性质的工作比如垃圾回收(GC)等服务型功能。一旦所有的非守护(即用户)线程结束,则整个虚拟机将会关闭,即使还有存活的守护线程也不会继续存在。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值