Java编程基本功大揭秘 | 详解深入分析Java的并发编程多线程技术,掌握实战技巧【1】

为什么要夯实基本功?

夯实编程基本功对于成为一名优秀的Java技术专家至关重要。它不仅帮助你建立坚实的基础,提高编程效率和问题解决能力,还为你学习和掌握更高级的技术打下了基础。因此,无论是初学者还是有经验的开发者,都应该注重夯实编程基本功。

  • 建立坚实的基础:夯实编程基本功可以帮助你建立坚实的编程基础,掌握核心概念和语法规则。这为你在后续的学习和实践中提供了稳定的基础,使你能够更好地理解和应用更高级的概念和技术。

  • 提高编程效率:掌握编程基本功可以提高你的编程效率。当你熟悉基本的语法和常用的编程技巧时,你能够更快地编写代码,减少错误和调试的时间,提高开发效率。

  • 增强问题解决能力:夯实编程基本功可以培养你的问题解决能力。当你熟悉基本的编程概念和技巧时,你能够更好地分析和解决编程问题,找到合适的解决方案。

  • 为学习高级技术打下基础:夯实编程基本功是学习和掌握更高级技术的基础。当你掌握了基本的编程概念和技巧后,你能够更轻松地理解和学习更高级的概念和技术,如面向对象编程、设计模式、并发编程等。


线程Thread

java.lang.Thread类

java 复制代码
Thread(Runnable target)

这个构造函数用于创建一个新的线程,其主要任务是执行提供的Runnable对象的run()方法。

java 复制代码
void start()

此方法用于启动线程,进而触发run()方法的执行。调用此方法后,会立即返回,此时新创建的线程将开始并行运行。

java 复制代码
void run()

这个方法被设计来调用与其关联的Runnable对象的run方法,以实现线程的具体任务。

java.lang.Runnable类

java 复制代码
void run()

必须重写这个方法,并在其中详细定义需要执行的具体任务指令。

线程状态

线程可以有如下6种状态,若要了解线程的当前状态,可通过调用getState方法来获取。线程可能会因为两种原因而终止:一种是因为run方法执行完毕而自然结束;另一种是因为run方法中抛出了一个未捕获的异常,导致线程意外终止。


中断线程

当线程的run方法执行到方法体中的最后一条语句,并通过执行return语句完成返回,或者在方法内部发生了未被捕获的异常时,该线程将会结束其执行。存在一种能够强制结束线程的方式,但更为推荐的做法是使用interrupt方法来请求线程终止。这种方式更为安全和可控。

Thread的中断方法

java 复制代码
void interrupt()

向线程发出中断请求后,其中断状态将被标记为true。倘若此时线程正被一个sleep调用所阻塞,那么将会抛出InterruptedException异常。

java 复制代码
static boolean interrupted()

检查当前正在执行命令的线程是否被中断,需要注意的是,这一操作是通过调用一个静态方法来实现的。这个方法会产生一个副作用,即将当前线程的中断状态重置为false。

java 复制代码
boolean isInterrupted()

检查线程是否已被中断,与静态的中断方法不同,这一操作不会改变线程的中断状态。

interrupt中断状态

调用线程的interrupt方法会将其中断状态设置为true,这是一个布尔类型的标志,每个线程都拥有。为了确保线程的正常运行,应定期检查此标志以确认线程是否已被中断。

java 复制代码
while (Thread.currentThread().isInterrupted() && more work to do)
	do more work
}

若要检测中断状态是否被触发,可首先通过调用Thread.currentThread静态方法获取当前运行的线程,随后使用isInterrupted方法来检查中断状态。

InterruptedException的作用

若线程处于阻塞状态,它将无法检测到中断信号。这正是InterruptedException发挥作用的时候。当一个被阻塞的线程(例如,正在调用sleepwait方法)上调用interrupt方法时,这个阻塞调用将会被InterruptedException打断,从而允许线程响应中断并作出相应处理。

注意,如果有不能被中断的阻塞I/O调用,应该考虑选择可中断的调用

在Java的编程规范中,并没有明确要求一个被中断的线程必须终止执行。中断线程仅仅是为了提醒或引起其注意。至于如何响应这一中断,完全取决于被中断线程自身的决定。有些线程由于其重要性,即使在遇到异常后也会选择继续执行,不受中断影响,在大多数情况下,线程会将中断视为一个请求其终止的信号,并据此作出相应处理。

这种线程的run方法具有如下形式:

java 复制代码
public void run()
try
	while (!Thread.currentThread().isInterrupted() && more work to do)
		do more work
	}
catch(InterruptedException e){
	thread was interrupted during sleep or wait
}finally
	cleanup,if required
}

若在每轮工作迭代后都调用sleep方法(或其他可被中断的方法),那么使用isInterrupted进行检测就显得多余且无实际意义。原因在于,一旦中断状态被设置,并且此时调用了sleep方法,线程将不会进入休眠状态。相反,sleep方法会清除中断状态,并抛出InterruptedException异常,如下所示:

java 复制代码
public void run()
try{
	while (more work to do){
		do more work
		Thread.sleep(delay);
	}
}catch(InterruptedException e)
	thread was interrupted during sleep
}finally{
	cleanup,if required
}

因此,如果你的循环中调用了sleep,那么无需检测中断状态。相反,你应该通过捕获InterruptedException异常来处理中断情况.

未捕获异常处理器

线程的run方法不允许抛出任何受检异常,未受检的异常若发生,则会导致线程结束执行。在这种情况下,线程将终止,即所谓的线程"死亡"。

对于可能传播的异常,并不需要使用catch子句来处理。相反,在线程终止之前,异常会被传递给一个专门处理未捕获异常的处理器。这个处理器必须是属于实现了Thread.UncaughtExceptionHandler接口的类的一个实例。该接口仅定义了一个方法,用于处理未捕获的异常。

java 复制代码
void uncaughtException(Thread t.Throwable e)

setUncaughtExceptionHandler方法,允许我们为特定线程设置一个异常处理器。此外,我们还能够利用Thread类的setDefaultUncaughtExceptionHandler静态方法,来为所有线程配置一个默认的异常处理器。这种机制的一个实际应用是,我们可以通过替换处理器,使用日志API将未捕获的异常报告自动发送到日志文件中,从而实现自动化的异常跟踪与记录。

设置或获取未捕获异常的默认处理器

java 复制代码
static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler);
static Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler();

设置或获取未捕获异常的处理器。如果没有安装处理器,则将线程组对象作为处理器。

java 复制代码
void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler);
Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();

如果存在父线程组,那么会调用父线程组的相应方法;若Thread类配置了默认处理器,则会调用该处理器来处理。如果这两者都不存在,系统会将异常的栈踪迹输出到标准错误流上。但需注意,若异常对象e是ThreadDeath类型(由已过时的stop方法产生),则不会打印栈踪迹。

相关推荐
zwhdlb12 分钟前
Java + 工业物联网 / 智慧楼宇 面试问答模板
java·物联网·面试
Pitayafruit13 分钟前
Spring AI 进阶之路04:集成 SearXNG 实现联网搜索
spring boot·后端·ai编程
风象南16 分钟前
SpringBoot 自研「轻量级 API 防火墙」:单机内嵌,支持在线配置
后端
刘一说28 分钟前
CentOS 系统 Java 开发测试环境搭建手册
java·linux·运维·服务器·centos
Victor35633 分钟前
Redis(14)Redis的列表(List)类型有哪些常用命令?
后端
Victor35633 分钟前
Redis(15)Redis的集合(Set)类型有哪些常用命令?
后端
卷福同学35 分钟前
来上海三个月,我在马路边上遇到了阿里前同事...
java·后端
bingbingyihao2 小时前
多数据源 Demo
java·springboot
在努力的前端小白7 小时前
Spring Boot 敏感词过滤组件实现:基于DFA算法的高效敏感词检测与替换
java·数据库·spring boot·文本处理·敏感词过滤·dfa算法·组件开发
bobz9659 小时前
小语言模型是真正的未来
后端