当前位置:网站首页 > Java基础 > 正文

java线程基础概念



文章目录

  • 进程与线程
    • 什么是进程?
    • 什么是线程?
    • 线程与进程的区别?
    • 单线程与多线程
  • 线程的四种创建方式
    • 1.方式一:继承 java.lang.Thread 类(线程子类)
    • 2.方式二:实现 java.lang.Runnable 接口(线程执行类)
    • 3.实现 java.util.concurrent.Callable 接口,允许子线程返回结果、抛出异常
    • 4.线程池
    • 5.线程的启动
  • 线程的休眠与优先级
    • 线程的休眠
    • 线程的优先级
  • 线程的状态
  • 线程的常见方法
    • 1.线程的插队:join()方法
    • 1.2.join()方法和sleep()方法的区别
    • 2.线程的中断:interrupt()方法
    • 3.线程的让出:yield()方法
    • 4.线程的等待:wait()方法
    • 5.线程的唤醒:notify()方法和notifyAll()方法
  • 守护线程
  • 总结


进程与线程

什么是进程?

进程是指在计算机中运行的程序的实例。它是操作系统进行资源分配和调度的基本单位。一个进程可以包含多个线程,每个线程都共享该进程的资源,如内存、文件和打开的网络连接等。每个进程都有自己的地址空间,即独立的内存区域。

什么是线程?

线程是进程内的执行单元,也是CPU的最小执行单元。一个进程可以包含多个线程,每个线程执行不同的任务。线程共享进程的资源,包括内存、文件和打开的网络连接等。线程之间通过共享内存进行通信,因此比进程间通信更高效。由于线程共享同一进程的地址空间,所以多线程之间的切换更快。

例如:我们启动JVM运行一个Java程序,其实就是启动了一个 JVM 的进程。在JVM的进程中,又包含了main :主线程Reference Handler:清理线程Finalizer:线程(用于调用对象 的finalize()方法)等线程。

线程与进程的区别?

  1. 根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位;
  2. 资源开销:每个进程都有独立的代码副本和数据空间,进程之间的切换,资源开销较大;线程可以看做轻量级的进程,每个线程都有自己独立的运行栈和程序计数器,线程之间切换,资源开销小;
  3. 内存分配:同一进程内的所有线程共享本进程的内存空间和资源;进程之间的内存空间和资源相互独立;
  4. 影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响;一个线程崩溃,会导致整个进程退出。所以多进程要比多线程健壮;
  5. 执行过程:每个独立的进程有程序运行的入口和程序出口。但是线程不能独立执行,必须依存在应用程序(进程)中,由应用程序提供多个线程执行控制;
  6. 包含关系:一个进程内包含有多个线程,在执行过程,线程的执行不是线性串行的,而是多条线程并行共同完成;

单线程与多线程

单线程:单线程指的是程序中只有一个主线程在执行任务。在单线程模型中,任务按顺序依次执行,每个任务必须等待前一个任务完成后才能执行。当一个任务发生阻塞(如等待I/O操作或进行复杂计算)时,整个程序都会被阻塞,无法执行其他任务。单线程模型简单,易于编写和调试,但其执行效率受限于单个线程的处理能力。

多线程:多线程指的是程序中同时存在多个线程,并发地执行不同的任务。每个线程独立执行,可以同时进行多个任务。多线程模型可以充分利用多核处理器和资源,提高程序的性能和响应速度。不同的线程可以并行执行独立的任务,当某个线程发生阻塞时,其他线程仍然可以继续执行,不会阻塞整个程序。多java线程基础概念线程编程需要注意线程安全、同步和数据共享等问题,避免出现竞态条件和死锁等并发问题。


线程的四种创建方式

为放方便整理,以下方法均采用匿名继承、匿名实现来完成。

1.方式一:继承 java.lang.Thread 类(线程子类)

 

2.方式二:实现 java.lang.Runnable 接口(线程执行类)

 

3.实现 java.util.concurrent.Callable 接口,允许子线程返回结果、抛出异常

 

4.线程池

线程池是线程中非常重要的一个知识点,此处不做详细介绍,只通过线程池创建一个线程对象。

 

5.线程的启动

通过调用Thread实例start()方法启动新线程。
start()方法内部调用了一个private native void start0()方法,native修饰符表示这个方法是由JVM虚拟机内部的C代码实现的本地方法,由JVM根据当前操作系统进行本地实现。

 

当线程启动后,它将在自己的执行路径上执行run()方法中的代码。


线程的休眠与优先级

线程的休眠

要使线程进入休眠状态,你可以使用Thread.sleep()方法。它使当前线程暂停执行一段指定的时间,然后再继续执行。
当线程调用 Sleep 后,它会进入阻塞状态,不会占用 CPU 资源。在指定的时间到达之前,线程不会被唤醒。Sleep 不会释放锁,因此其他线程无法访问被当前线程锁住的资源。

Thread.sleep()方法有两种重载形式:

 

线程的优先级

 

注意:并不能代表,通过设置优先级来确保高优先级的线程一定会先执行,只是会提高一定的优先级。


线程的状态

在Java程序中,一个线程对象通过调用start()方法启动线程,并且在线程获取CPU时,自
动执行run()方法。run()方法执行完毕,代表线程的生命周期结束
在整个线程的生命周期中,线程的状态有以下6种:

  • new:新建状态,新创建的线程,此时尚未调用start()方法;
  • Runnable:运行状态,运行中的线程,已经调用了start()方法,线程正在或即将被执行;
  • Blocked:阻塞状态,运行中的线程,在等待竞争锁时,被阻塞,暂不执行;
  • Waiting:等待状态,运行中的线程,因为sleep()方法、join()方法等方法的调用,进入等待;
  • Timed Waiting:计时等待状态,运行中的线程,因为执行sleep(等待毫秒值)join(等待毫秒值)等方法,进入计时等待;
  • Terminated:终止状态,线程已经终止,因为run()方法已经执行完毕;
    当线程启动后,它可以在Runnable、Blocked、Waiting和Timed Waiting这几个状态之间切换,直到最后变成Terminated状态,线程终止。

线程的常见方法

1.线程的插队:join()方法

join() 方法是 Thread 类的实例方法,可以在一个线程中调用另一个线程的 join() 方法等待其执行完成,并等待 线程t 执行完毕后才会被唤醒。此时,并不影响同一时刻处在运行状态的其他线程。
join() 方法是基于协作的线程间等待,调用线程会等待被等待线程执行完毕,期间不会释放锁资源

 

join()方法的底层是利用wait()方法实现;

1.2.join()方法和sleep()方法的区别

  1. 两个方法都可以实现类似"线程等待"的效果,但是仍然有区别;
  2. join()是通过在内部使用synchronized + wait()方法来实现的,所以join()方法调用结束后,会释放锁;
  3. sleep()休眠没有结束前,不会释放锁;

2.线程的中断:interrupt()方法

interrupt() 方法用于中断正在运行的线程。当调用 interrupt() 方法时,它会将线程的中断状态设置为 “中断”,但并不会直接停止线程的执行。当线程被中断时,它可以选择如何响应中断。线程可以通过检查自己的中断状态并采取适当的行动来响应中断。例如,线程可以选择继续执行,或者可以选择终止自己的执行。
支持线程中断的方法(Thread.sleep() 、join()、wait()等方法)就是在监视线程的中断状态,一旦发现线程的中断状态值被置为“true”,就会抛出线程中断的异常InterruptedException,给WAITING或者TIMED_WAITING等待状态的线程发出一个中断信号,线程检查中断标识,就会以退出WAITING或者TIMED_WAITING等待状态;

 

3.线程的让出:yield()方法

yield() 方法用于提示线程调度器当前线程愿意放弃对 CPU 的使用,以便其他具有相同优先级的线程有机会执行。调用 yield() 方法会暂停当前正在执行的线程,并将执行机会交给其他具有相同优先级的线程。

 

需要注意的是,yield() 方法仅仅是提供了一种提示,实际的线程调度行为由 JVM 的实现和操作系统的调度器来决定。因此,对于不同的 JVM 和操作系统,yield() 方法的行为可能会有所不同。另外,yield() 方法不会释放线程持有的锁

4.线程的等待:wait()方法

wait() 方法是 Object 类的实例方法,需要在同步代码块或同步方法中调用,即在持有锁的情况下才能调用。该方法会使当前线程进入等待状态释放对象锁资源,(会使当前线程让出持有的"this锁",允许其它线程参与竞争CPU执行权(this锁),而sleep的休眠过程中,当前线程不会让出持有锁!!!)等待其他线程调用相同对象的 notify() 或 notifyAll() 方法来唤醒。

 

5.线程的唤醒:notify()方法和notifyAll()方法

线程的唤醒指的是从等待状态(如调用了wait()方法)中唤醒线程,使其继续执行;
在Java中,线程的唤醒方法有:
notify()方法:随机唤醒等待的某个线程;
notifyAll()方法:唤醒全部等待线程;

 

等待线程通过调用this.wait()方法进入等待状态,释放锁,并等待唤醒信号,等待线程将继续执行后续的代码。


守护线程

守护线程(Daemon Thread)是一种特殊类型的线程,它的存在并不会阻止 JVM 的退出。当所有的非守护线程都结束时,守护线程会自动终止。
在调用start()方法前,调用setDaemon(true)把该线程标记为守护线程。


                            

  • 上一篇: 有php基础学java
  • 下一篇: java基础和javase
  • 版权声明


    相关文章:

  • 有php基础学java2025-04-01 20:02:06
  • java基础组件漏洞2025-04-01 20:02:06
  • java语言编程基础2025-04-01 20:02:06
  • java基础教程百度云2025-04-01 20:02:06
  • java基础375讲2025-04-01 20:02:06
  • java基础和javase2025-04-01 20:02:06
  • java零基础学拼音2025-04-01 20:02:06
  • java语言基础boolean2025-04-01 20:02:06
  • java基础jar包2025-04-01 20:02:06
  • java基础面试项目2025-04-01 20:02:06