线程基础

本文介绍了Java中线程的基础知识,包括线程与进程的区别,线程的创建(继承Thread类、实现Runnable接口以及使用匿名内部类),线程的生命周期及其六个状态,并解析了start、sleep、join、notify和notifyAll等常用线程方法。

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

1)线程和进程的概念

进程线程
一段正在运行的程序程序运行中可以执行的多个任务叫线程
进程是程序执行过程中资源分配和管理的基本单位线程是cpu执行的最小单位
有独立的内存空间,进程中的数据存放空间(堆空间和栈空间)是独立的堆空间是共享的,栈空间是独立的
线程是轻量级的进程

在这里插入图片描述

多线程作为一种多任务、并发的工作方式,其存在优势:
①进程之前不能共享内存,而线程之间共享内存(堆内存)则很简单。
②系统创建进程时需要为该进程重新分配系统资源,创建线程则代价小很多,因此实现多任务并发时,多线程效率更高。
③Java语言本身内置多线程功能的支持,而不是单纯第作为底层系统的调度方式从而简化了多线程编程

2)线程的创建

创建和启动线程,传统有两种方式
方式1):继承Thread类
方式2):实现Runnable接口
方式3):使用匿名内部类的方式来创建线程

线程类(java.lang.Thread): Thread类和Thread的子类才能被称为线程类。

方式1
1):定义一个类A继承于java.lang.Thread类.
2):在A类中覆盖Thread类中的run方法
3):我们在run方法中编写需要执行的操作—>run方法里是线程执行体.
4):在main方法(主线程)中,创建线程对象并启动线程.

class MusicThread extends java.lang.Thread{
    @Override
    public void run() {
        for(int i=0;i<20;i++){
            System.out.println("播放音乐"+i);
        }
    }
}

//方法一:继承Thread类
public class ExtendsThreadDemo {
    public static void main(String[] args) {
        for(int i=0;i<20;i++){
            System.out.println("打游戏"+i);
            if(i == 10){
                //创建线程对象,并启动线程
                MusicThread musicThread=new MusicThread();
                musicThread.start();//启动线程,不能调用run方法
            }
        }
    }
}

结果可以边打游戏边听歌
在这里插入图片描述
方式2
1):定义一个类A实现于java.lang.Runnable接口,注意A类不是线程类。
2):在A类中覆盖Runnable接口中的run方法。
3):我们在run方法中编写需要执行的操作—>run方法里的,线程执行体。
4):在main方法(线程)中,创建线程对象,并启动线程.

//播放音乐类
class MuslicRunnableImplements implements java.lang.Runnable{
    @Override
    public void run() {
        for(int i=0;i<50;i++){
            System.out.println("播放音乐"+i);
        }
    }
}

//方式二:实现Runnable接口

    //打游戏主类
public class ImplementsRunnableDemo {
    public static void main(String[] args) {
        for(int i=0;i<50;i++){
            System.out.println("打游戏"+i);
            if(i == 10){
                //创建线程对象,并启动线程
                Runnable target= new MuslicRunnableImplements();
                Thread t=new Thread(target);
                t.start();
            }
        }
    }
}

结果也可以边打游戏边听歌
在这里插入图片描述
***方式三***匿名内部类的方式
注意:只适用于一个类只使用一次的情况

public class AnonymousInnerClassDemo {
    public static void main(String[] args){
        //主进程:运行游戏
        for(int i=0;i<50;i++){
            System.out.println("打游戏"+i);
            if(i == 10){
                /**
                 * 使用类的形式的匿名内部类
                 */
                new Thread(){
                    @Override
                    public void run() {
                        for(int i=0;i<50;i++){
                            System.out.println("播放音乐"+i);
                        }
                    };
                }.start();
            }
        }
    }
}

结果也可以边打游戏边听歌
在这里插入图片描述

3)线程的生命周期及常用方法解析

线程生命周期的6种状态
1:新建状态(new):
使用new创建一 个线程对象,仅仅在堆中分配内存空间,在调用start方法之前.新建状态下,线程压根就没有启动,仅仅只是存在一个线程对象而已.
Thread t = new Thread();//此时t就属于新建状态
当新建状态下的线程对象调用了start方法此时从新建状态进入可运行状态.
线程对象的start方法只能调用一次,否则报错。

2:可运行状态/就绪状态(runnable):可运行线程状态正在Java虚拟机中执行,但它可能等待来自操作系统的其他资源
分成两种状态, ready和running。 分别表示就绪状态和运行状态。
就绪状态:线程对象调用start方法之后,等待JVM的调度(此时该线程并没有运行).
运行状态:线程对象获得JVM调度如果存在多个CPU,那么允许多个线程并行运行.

3:阻塞状态(blocked):
正在运行的线程因为某些原因放弃CPU,暂时停止运行,就会进入阻塞状态此时JVM不会给线程分配CPU,直到线程重新进入就绪状态,才有机会转到运行状态,阻塞状态只能先进入就绪状态,不能直接进入运行状态。

阻塞状态的两种情况:
1):当A线程处于运行过程时,试图获取同步 锁时,却被B线程获职.此时vM把当前A线程存到对象的锁池中,A线程进入阻塞状态。
2):当线程处于 运行过程时,发出了IO请求时,此时进入阻塞状态。

4:等待状态(waiting)(等待状态,只能被其他线程唤醒)此时使用的无参的wait方法。
1):当线程处于运行过程时,调用了wait()方法,此时JvM把当前线程存在对象等待池中。
2):当前线程执行了sleep()方法。

5:睡眠/计时等待状态(timed waiting)(使用了带参数的wait方法或者sleep方法)
1):当线程处于运行过程时,调用了wait(long time)方法此时JVM把当前线程存在对象等待池中。
2):当前线程执行了sleep(long time)方法。

6:终止状态(terminated):通常称为死亡状态,表示线程终止。
1):正常执行完run方法而退出。
2):遇到异常而退出。(遇到异常,程序就会中断)
在这里插入图片描述
有关线程的常用方法
1、start():线程状态会从New状态转换到Runnable状态,使该线程开始执行,然后获取Cpu之后进入Running状态然后Java 虚拟机调用该线程的 run 方法。
2、sleep():使得线程进入睡眠状态,暂停执行
●public static native void sleep(long millis)该线程睡眠时间为 millis 毫秒。
●public static void sleep(long millis, int nanos)该线程睡眠时间millis 毫秒 + nanos 纳秒
jdk1.5之后,jdk引入一个枚举TimeUnit,其对sleep方法做了封装,直接使用从而时间单位换算的步骤
3、join():在线程B中join某个线程A,会使得B线程进入等待,直到线程A结束生命周期,或者达到给定的时间,在这期间线程B会处于等待状态。
4、notify():唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。
5、notifyAll():唤醒在此对象监视器上等待的所有线程。
6、interrupt():线程中断方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值