多线程系列之创建和启动

本文介绍了Java中线程的概念,包括进程、线程和它们的关系,重点讲解了如何通过继承Thread类和实现Runnable接口创建线程,以及常用的方法如currentThread()、setName()等。此外,文章详细剖析了线程的生命周期状态和管理技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多线程系列之创建和启动

一 线程相关概念

  1. 进程
    进程是计算机程序的一次运行活动,是操作系统进行资源分配和调度的基本单位。
  2. 线程
    线程是进程的一个执行单元,一个线程就是进程中一个单一顺序的控制流, 进程的一个执行分支;进程是线程的容器,一个进程至少有一个线程.一个进程中也可以有多个线程;在操作系统中是以进程为单位分配资源,如虚拟存储空间,文件描述符等. 每个线程都有各自的线程栈,寄存器环境和线程本地存储。
  3. 主线程和子线程
    JVM 启动时会创建一个主线程,该主线程负责执行 main 方法,主线程就是运行main方法的线程。
    如果A线程中创建了B线程,B线程就是A线程的子线程,A线程就是B线程的父线程。
  4. 串行,并发,并行
    串行:按顺序执行
    并发:在同一时间间隔内执行
    并行:在同一时间执行
    如图所示:
    在这里插入图片描述

二 线程的创建和启动

  1. 两种常用的创建线程的方法
    (1)定义 Thread 类的子类
    说明:
    调用线程的 start()方法来启动线程, 启动线程的实质就是请求 JVM 运行相应的线程,这个线程具体在什么时候运行由线程调度器(Scheduler)决定
    注意:
    start()方法调用结束并不意味着子线程开始运行,新开启的线程会执行 run()方法,如果开启了多个线程,start()调用的顺序并不一定就是线程启动的顺序,多线程运行结果与代码执行顺序或调用顺序无关
//1.定义线程类继承Thread
public class MyThread extends Thread{
	//2. 重写 Thread 父类中的 run()
	//run()方法体中的代码就是子线程要执行的任务
	@Override
	public void run() {
		System.out.println("这是子线程打印的内容");
	}
}
public class Test {
	public static void main(String[] args) {
		System.out.println("JVM 启动 main 线程,main 线程执行 main 方法");
		//3.创建子线程对象
		MyThread thread = new MyThread();
		//4.启动线程
		thread.start();
		System.out.println("main 线程后面其他 的代码...");
	}
}

(2)定义类实现Runnable接口

//1. 定义类实现Runnable接口
public class MyRunnable implements Runnable {
	//2.重写 Runnable 接口中的抽象方法 run(), run()方法就是子线程要执行的代码
	@Override
	public void run() {
		for(int i = 1; i<=1000; i++){
			System.out.println( "sub thread --> " + i);
		}
	}
}

public class Test {
	public static void main(String[] args) {
		//3. 创建 Runnable 接口的实现类对象
		MyRunnable runnable = new MyRunnable();
		//4.创建线程对象
		Thread thread = new Thread(runnable);
		//5.开启线程
		thread.start();
		//当前是 main 线程
		for(int i = 1; i<=1000; i++){
			System.out.println( "main==> " + i);
		}
		//有时调用 Thread(Runnable)构造方法时,实参也会传递匿名内部类对象
		Thread thread2 = new Thread(new Runnable() {
			@Override
			public void run() {
				for(int i = 1; i<=1000; i++){
					System.out.println( "sub ------------------------------> " + i);
				}
			}
		});
		thread2.start();
	}
}

三 线程的常用方法

  1. currentThread()方法
    Thread.currentThread()方法可以获得当前线程,方法的返回值是在代码实际运行时候的线程对象。
  2. setName()/getName()方法
    thread.setName(线程名称), 设置线程名称
    thread.getName()返回线程名称
  3. isAlive()方法
    thread.isAlive()判断当前线程是否处于活动状态,活动状态就是线程已启动并且尚未终止。
  4. sleep()方法
    Thread.sleep(millis); 让当前线程休眠指定的毫秒数
  5. getId()方法
    thread.getId()可以获得线程的唯一标识,某个编号的线程运行结束后,该编号可能被后续创建的线程使用,重启的 JVM 后,同一个线程的编号可能不一样
  6. yield()方法
    Thread.yield()方法的作用是放弃当前的 CPU 资源,线程让步
  7. setPriority()方法
    thread.setPriority( num ); 设置线程的优先级,java 线程的优先级取值范围是 1 ~ 10 , 如果超出这个范围会抛出异常 IllegalArgumentException.。在操作系统中,优先级较高的线程获得 CPU 的资源越多,优先级只是便于调度器决定先调度哪些线程,不能保证优先级高的线程先运行。线程的优先级具有继承性,即在A线程中创建了B线程则B线程优先级和A线程一样。
  8. interrupt()方法
    interrupt()方法中断线程,它仅仅是在当前线程打一个停止标志,并不是真正的停止线程。
  9. setDaemon()方法
    Java 中的线程分为用户线程与守护线程,守护线程是为其他线程提供服务的线程,如垃圾回收器(GC)就是一个典型的守护线程。守护线程不能单独运行, 当 JVM 中没有其他用户线程,只有守护线程时,守护线程会自动销毁, JVM 会退出。

四 线程的生命周期

线程的生命周期可以使用getState()方法获得,线程的状态在Thread.State枚举类型定义的,有以下几种:
(1)NEW:新建状态,创建线程对象
(2)RUNNABLE:可运行状态,包括READY和RUNNING两个状态,READY 状态该线程可以被线程调度器进行调度使它处于 RUNNING 状 态 , RUNNING 状 态 表 示 该 线 程 正 在 执 行 。Thread.yield()方法可以把线程由 RUNNING 状态转换为 READY 状态。
(3)BLOCKED:阻塞状态,线程发起阻塞的 I/O 操作,或者申请由其他线程占用的独占资源,线程会转换为 BLOCKED 阻塞状态.。处于阻塞状态的线程不会占用CPU 资源.,当阻塞I/O 操作执行完,或者线程获得了其申请的资源,线程可以转换为RUNNABLE。
(4)WAITING :等待状态,线程执行了 object.wait(), thread.join()方法会把线程转换为 WAITING 等待状态, 执行 object.notify()方法,或者加入的线程执行完毕,当前线程会转换为 RUNNABLE 状态
(5)TIMED_WAITING:等待状态,处于该状态的线程不会无限的等待,如果线程没有在指定的时间范围内完成期望的操作,该线程自动转换为 RUNNABLE
(6)TERMINATED:终止状态,线程结束处于该状态。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值