JavaEE初阶:Java线程的状态

目录

获取当前线程引用

休眠当前线程

线程的状态

1.NEW

2.TERMINATED

3.RUNNABLE

4.WAITING

5.TIMED_WAITING

6.BLOCKED

多线程的意义

单线程

多线程


获取当前线程引用

java 复制代码
public static Thread currentThread(); 

这个方法返回当前线程的引用。但是我们会对static有疑惑,这其实是一个静态方法,更好的说法是这是一个**类方法,**调用这个方法,不需要实例,直接通过类名来调用。

可以直接通过Thread.currentThread(),不一定要t.currentThread()

在哪个线程中调用,就能获取到哪个线程的实例.

java 复制代码
public class ThreadDemo {
    public static void main(String[] args) {
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName());
   }
}

休眠当前线程

java 复制代码
public static void sleep(long millis)

让线程休眠,本质上就是让这个线程不参与调度了,不去cpu上执行

线程的状态

状态是针对当前的线程调度的情况来描述的

咱们现在认为,线程是调度的基本单位了 状态更应该是线程的属性。

在Java对于线程的状态,进行了细化:

1.NEW

创建了Thread对象,但是还没调用start(内核里还没创建对应的PCB)

2.TERMINATED

表示内核中的pcb已经执行完毕了,但是Thread对象还在

一但内核里的线程PCB消亡了,此时代码中t对象也就没啥用了,但是还存在

Java中的对象有生命周期,自有其规则,内核的线程释放的时候无法保证Java代码中t对象也立刻释放

因此势必就会存在内核的PCB没了,但是代码中的t还在这样的情况,此时就需要通过特定的状态,来把t对象标识成"无效"

3.RUNNABLE

a)正在CPU上执行的

b)在就绪队列里,随时可以去CPU上执行

4.WAITING

5.TIMED_WAITING

6.BLOCKED

通过getState可以获取当前进程的状态:​​​​​​​

此处能看到RUNNABLE,主要就是因为当前线程run里面,没有写任何sleep之类的方法。

多线程最核心的地方:抢占式执行,随机调度。

多线程的意义

我们写个案例来了解一下多线程的意义:

我们通过写一个运算量很大的任务,看一下多线程和单线程的区别

单线程

java 复制代码
public class demo {
    public static void main(String[] args) {
        serial();
    }

    public static void serial(){
        long beg = System.currentTimeMillis();

        long a = 0;
        for(long i = 0 ; i < 100_0000_0000L ; i++){
            a++;
        }

        long b = 0;
        for(long j = 0 ; j < 100_0000_0000L ; j++){
            b++;
        }
        long end = System.currentTimeMillis();
        System.out.println("执行时间" + (end-beg) + "ms");
    }
}

执行时间6599ms

进程已结束,退出代码0

通过运行一个重复一百亿的加法,可以得到这个线程的运行时间

用currentTimeMilis获取开始和结束的时间,打印出来两者之差,粗略的能得到运行的时间

多线程

java 复制代码
    public static void concurrency(){
        Thread t1 = new Thread(() -> {
            long a = 0;
            for(long i = 0 ; i < 100_0000_0000L ; i++){
                a++;
            }
        });

        Thread t2 = new Thread(() -> {
            long b = 0;
            for(long j = 0 ; j < 100_0000_0000L ; j++){
                b++;
            }
        });

        long beg = System.currentTimeMillis();
        t1.start();
        t2.start();
        long end = System.currentTimeMillis();
        System.out.println("执行时间" + (end-beg) + "ms");
        
    }

执行时间0ms

进程已结束,退出代码0

通过Lambda表达式新建两个线程,注意此时有main、t1、t2三个线程,我们把刚刚main线程的工作放在t1、t2中,这样在两个线程中分别进行循环

但是为什么最后的执行时间是0ms呢,是因为线程是独立运行的,执行时间的判定是在main线程中单独完成,也就是没有等待t1t2执行完再返回时间,所以我们需要加入join来让main线程等待其完成:

可以看到时间近乎缩短了一半,这就是多线程相对于单线程的优势,可以更加充分的利用CPU多核心的能力,但是时间又不是刚好缩短了一半:

多线程,在这种CPU密集型的任务中有非常大的作用,可以充分利用CPU的多核资源,从而加快程序的运行效率。

但是不是说使用多线程,就能一定提高效率:

1.是否是多核(现在的CPU基本都是多核了)

2.当前核心是否空闲(如果CPU这些核心已经都满载了,这个时候启动更多的线程也啥用)

相关推荐
小麟有点小靈4 分钟前
VSCode写java时常用的快捷键
java·vscode·编辑器
程序猿chen15 分钟前
JVM考古现场(十九):量子封神·用鸿蒙编译器重铸天道法则
java·jvm·git·后端·程序人生·java-ee·restful
xiongmaodaxia_z719 分钟前
python每日一练
开发语言·python·算法
Chandler2433 分钟前
Go:接口
开发语言·后端·golang
Jasmin Tin Wei34 分钟前
css易混淆的知识点
开发语言·javascript·ecmascript
&白帝&34 分钟前
java HttpServletRequest 和 HttpServletResponse
java·开发语言
ErizJ35 分钟前
Golang|Channel 相关用法理解
开发语言·后端·golang
automan0235 分钟前
golang 在windows 系统的交叉编译
开发语言·后端·golang
仙人掌_lz1 小时前
详解如何复现DeepSeek R1:从零开始利用Python构建
开发语言·python·ai·llm·deepseek
小宁学技术1 小时前
MATLAB在哪些特定领域比Python更有优势?
开发语言·python·matlab