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

为什么要夯实基本功?

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

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

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

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

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


线程Thread

java.lang.Thread类

Thread(Runnable target)

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

void start()

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

void run()

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

java.lang.Runnable类

void run()

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

线程状态

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


中断线程

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

Thread的中断方法

void interrupt()

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

static boolean interrupted()

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

boolean isInterrupted()

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

interrupt中断状态

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

while (Thread.currentThread().isInterrupted() && more work to do)
	do more work
}

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

InterruptedException的作用

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

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

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

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

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异常,如下所示:

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接口的类的一个实例。该接口仅定义了一个方法,用于处理未捕获的异常。

void uncaughtException(Thread t.Throwable e)

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

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

static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler);
static Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler();

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

void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler);
Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();

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

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洛神灬殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值