IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java并发编程(一):多线程与并发原理回顾 -> 正文阅读

[Java知识库]Java并发编程(一):多线程与并发原理回顾

在这里插入图片描述
今天来聊一聊经典的Java技术,并发编程。并发是程序的灵魂,一个优秀的Java程序一定会支持高并发,并且,并发编程也是面试环节中经常会问到的一个问题,那么今天我们以一道经典的Java面试题回顾一下Java的并发编程。废话不多说,直入正题…
在这里插入图片描述

请你简单讲一下什么是线程?在Java中创建线程有几种方式?Java中的线程有哪些特点?

答:线程是比进程更细致的独立单位,线程是CPU调度与分派的最小单位。在Java中创建线程的方式一共有两种:一种是继承Thread类完成对Thread类的扩展,进而实现线程的创建,另一种是实现Runnable接口。从代码层面来解读就是如下:

// @fntp--Java多线程系列笔记
public class MyThread extends Thread {
	@Override
	public void run() {
		while (true) {
		System.out.println(Thread.currentThread().getName() + " 运?了");
			try {
				Thread.sleep(1000);
				} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

然后我们可以在测试方法或者Main方法中进行测试:
请读者不要看不起这不起眼的代码,其实内部蕴含着很深的奥妙。比如这里调用的Start()方法,start()方法从英文翻译的角度字面意思来看,就是启动线程,也就是将调用该方法的线程的当前状态从创建-就绪状态转向运行时状态

// @fntp--Java多线程系列笔记
public static void main(String[] args) {
	MyThread thread = new MyThread();
	thread.start();
}

实现Runnable接口方式:

// @fntp--Java多线程系列笔记
public class MyRunnable implements Runnable {
	@Override
	public void run() {
	while (true) {
		System.out.println(Thread.currentThread().getName() + " 运?了");
		try {
			Thread.sleep(800);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

然后我们可以在测试方法或者Main方法中进行测试:

// @fntp--Java多线程系列笔记
public static void main(String[] args) {
	Thread thread = new Thread(new MyRunnable());
	thread.start();
}

在Java程序中,不论是并发还是单线程程序,都会存在一个名为主线程Thread对象。在JVM(Java虚拟机)执行Java程序时,Java虚拟机会创建一个Thread来执行Main方法。也就是说,Java中的Main方法在执行的时候,也是以线程的形式存在于Java虚拟机中。
以上描述,值得注意的点是:

  1. Java中任何程序不论并发与否,只要启动Jav程序,那么就必定存在主线程。
  2. Java中的多线程,线程与线程之间共享Java应用程序的所有资源。[1]
  3. Java中线程都具备优先级[2]。
  4. Java中主动创建线程时,可以创建以下两类线程:(1)守护线程(2)非守护线程。
  5. 线程具备六种状态:
    (1)NEW:新建状态。
    (2)RUNNABLE:可运行状态,我不建议称作就绪状态,原因下文会解释。
    (3)BLOCKED:阻塞状态。
    (4)WAITING:等待状态。
    (5)TIMED_WAITING:定时等待状态。
    (6)TERMINATED:终止状态。

[ 1 ] 这里的资源则包括内存,与存在于内存中的文件、对象、变量等资源,线程之间快速?简单地共享应用程序的信息。需要注意的是:必须使?同步避免线程与线程之间发生数据竞争。
[ 2 ] Java中线程的优先级数值存在一定的范围,优先级数值介于Thread.MIN_PRIORITY(1)与Thread.MAX_PRIORITY(10)之间,默认优先级是Thread.NORM_PRIORITY(5),具体的优先级起不起作用需要关注操作系统对线程优先级的支持,线程的优先级无法一定保证优先级,只能提高优先调度的概率。

以上主要讲解了Java中线程的基本概念,以及线程的创建方式方法,以及线程的五点值得关注的主要性质。对于线程的状态,我以JDK11最新版11.0.13版本作为源码样本,进行详致讲解。如下图所示:这里我们先关注两个点,Thread的内部静态方法getState()方法的用途与返回值。
图1-1
在这里插入图片描述
我们不难发现,Thread内部的State是一个枚举类。线程的状态获取底层是通过jdk.internal.misc.VM.toThreadState()方法进行实现的,该方法需要传入一个Int类型的数据,这个方法的底层实现逻辑如下图:
在这里插入图片描述
一方面,这充分说明了,在Thread类中,线程状态是固定的范围,一共六种状态,上面已做列举。每一种状态使用不同的数值进行表示。将传入的数值与JVMTI_THREAD_STATE常量进行按位与,从而计算按位与的结果。值得一提的是,JVMTI_THREAD_STATE 字段也就是线程状态字段是根据虚拟机在hotspot中实现状态转换时设置的。它的值是根据 JVM-TI 规范中的 GetThreadState () 函数设置的。
在这里插入图片描述
到现在为止,线程的状态获得的底层原理已经有了一个初步的大概,但对于线程的六种状态之间的切换是怎么操作的我们还没有一个明确的答案,接下来,我们一起来看一下线程切换的流程。下图:线程流程图,选图来自CSDN博主【m0_37779570】。
在这里插入图片描述
从这张图中,我们可以清晰的看出线程对象在调用start()方法后进入了RUNNABLE状态,进入RUNNABLE状态并不意味着就能立马执行,而是等待CPU线程调度器进行选择调度,当线程被调度后,才会进入运行中状态,但是如果此时调用了yield()方法,就会让线程重新回到就绪状态。

在线程处于RUNNABLE期间,此时发起阻塞IO操作会导致线程进入BLOCKED状态,当阻塞IO操作结束,又会重新回到RUNNABLE状态,当操作申请锁时,会进入阻塞状态,在获得锁后,又会进入RUNNABLE状态。

当处于RUNNABLE状态的线程调用了wait() 方法后,线程会进入WAITING状态,当被其他对象调用了notify() 或者notifyAll() 方法进行线程唤醒后,又会重新进入RUNNABLE状态,等待CPU调度。

当处于RUNNABLE状态的线程调用了Sleep() 方法后,线程会进入TIMED_WAITING状态,执行结束后又会及进入RUNNABLE状态。

特别注意!在给定的单位时间内,线程只能处于一个状态。

这里所涉及的所有线程状态,均来自于JVM-java虚拟机规范中的线程状态,不能类比操作系统的线程状态。

特别注意这里的RUNNABLE,我为什么不建议将RUNNABLE状态称之为就绪状态?因为RUNNABLE细分的话还包括就绪状态与执行中状态,这个RUNNABLE要从字面意思去理解更好理解一些,RUNNABLE代表着线程处于可执行状态,但是可执行并不代表着线程就处于执行状态,线程是否真正处于执行状态是取决于CPU的时间片与其他资源分配的。简而言之,就是说,线程处于就绪状态后,需要等待CPU分配系统资源才能进入RUNNING运行中状态;在处于RUNNABLE状态后,如果未获得CPU分配的系统资源,那么就会处于READY就绪状态。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-06-01 15:02:20  更:2022-06-01 15:04:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:04:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码