你好,我是忆~遂愿,全网2w+粉丝,《遂愿盈创》社群主理人。
副业启航① | 遂愿盈创(对副业感兴趣免费可入,多种赚钱实战项目等你来,一起探寻副业快速变现的途径;以及对接互联网大厂商务合作,一起来搞点小外快,认识更多互联网大咖)
目前群里已经带很多小伙伴(大部分大学生)变现几百块啦,程序员搞副业有额外加成~
对副业感兴趣可+V : suiyuan2ying
拉你进群。
文章目录
- 1 什么是守护线程,它的使用场景是什么?如何创建守护线程 ?
- 2 什么是 Thread 的中断标志?怎么设置和检查它?
- 3 Thread 的中断标志与 InterruptedException 有什么关系?
- 4 Object类的 wait,notify 和 notifyAll 方法的目的是什么 ?
1 什么是守护线程,它的使用场景是什么?如何创建守护线程 ?
想象一下,一个大型音乐会。音乐会的主要演出是乐队的表演,这就是主线程。乐队在舞台上演奏音乐,吸引观众的注意。舞台的清洁工则是后台支持人员,他们的工作是不断清理舞台上的杂物,确保乐队的演出能够顺利进行。清洁工并不要求乐队完成演出后再开始工作,而是随时在后台默默地工作。当音乐会结束时,清洁工也会跟着结束,不会再继续工作。
守护线程是指那些在后台运行,支持应用程序的主要任务的线程。它们的存在目的是提供必要的服务,比如垃圾回收或定时任务或定期清理缓存或监控系统状态,这些线程在应用程序的其他部分完成时会自动结束。
一个日志记录线程可以作为守护线程,在应用程序运行期间持续记录日志,而不会阻止应用程序的结束。
创建守护线程很简单,只需要设置线程的守护标志。在 Java 中,线程的守护状态通过 Thread.setDaemon(true)
方法设置。
public class DaemonThreadExample {public static void main(String[] args) {Thread daemonThread = new Thread(() -> {while (true) {// 会每秒打印一行信息System.out.println("守护线程正在运行...");try {// 守护线程失眠 1 秒Thread.sleep(1000); } catch (InterruptedException e) {Thread.currentThread().interrupt();}}});// 设置为守护线程daemonThread.setDaemon(true); // 启动守护线程daemonThread.start(); try {// 主线程休眠 5 秒Thread.sleep(5000); } catch (InterruptedException e) {Thread.currentThread().interrupt();}// 主线程睡眠 5 秒后结束,这时守护线程也会随着主线程的结束而终止System.out.println("主线程结束");}
}
2 什么是 Thread 的中断标志?怎么设置和检查它?
想象一下,一个工人在工地上忙碌地工作。他的任务是修建一条道路,工地上设有一个“停工指示牌”,这个指示牌用来告诉工人是否需要停下来并等待进一步的指示 ,当工人看到这个指示牌上写着“停工”时,他就知道需要暂时停止手头的工作。
线程的中断标志是一种机制,用于通知线程它应该停止当前的工作并退出,线程的中断标志并不直接终止线程,而是提供了一种与线程交互的方式,让线程可以在适当的时候响应终止请求。
每个线程都有一个中断标志,这个标志可以被设置、检查或清除。中断标志的状态可以通过两个主要的方法来操作:Thread.interrupt()
和 Thread.isInterrupted()
。
线程的中断标志可以通过调用 Thread.interrupt()
方法设置,当这个方法被调用时,线程的中断标志被标记为 true
。
不过,仅仅设置中断标志并不会立即停止线程的执行,线程需要在自己的代码中定期检查中断标志,并做出响应。
Thread thread = new Thread(() -> {// 检查线程的中断标志while (!Thread.currentThread().isInterrupted()) {// 执行一些工作System.out.println("线程正在运行...");try {// 模拟工作Thread.sleep(1000); } catch (InterruptedException e) {// 捕获到中断异常时,将线程的中断标志重新设置为 trueThread.currentThread().interrupt();}}
});
如果线程正在执行 Thread.sleep()
、Object.wait()
或 Thread.join()
等方法时被中断,这些方法会抛出 InterruptedException
异常。
在捕获到这个异常后,应该重新设置中断标志,以确保中断信号能够被正确处理。这个动作通过 Thread.currentThread().interrupt()
方法完成。
要设置线程的中断标志,可以在其他线程中调用 Thread.interrupt()
方法。
Thread thread = new Thread(() -> {// 工作线程中的循环会因为 isInterrupted() 返回 true 而结束,从而使线程终止while (!Thread.currentThread().isInterrupted()) {System.out.println("线程正在运行...");try {// 线程被阻塞,等待 10 秒Thread.sleep(10000);} catch (InterruptedException e) {// 捕获到中断异常,线程被中断System.out.println("Thread was interrupted!");// 保持中断标志状态Thread.currentThread().interrupt(); }}
});thread.start();
try {// 让线程运行一段时间,然后中断它Thread.sleep(1000);thread.interrupt();
} catch (InterruptedException e) {e.printStackTrace();
}
3 Thread 的中断标志与 InterruptedException 有什么关系?
线程的中断标志与 InterruptedException
紧密相关,每个线程都有一个中断标志,用来指示线程是否应该停止当前的操作。当这个标志被设置为中断时,线程就会响应这个请求。
当线程执行一些可能会被中断的操作,比如 Thread.sleep()
、Object.wait()
或 Thread.join()
时,它们会被阻塞。这时候,如果其他线程调用了 interrupt()
方法来中断这个线程,那么这些操作会抛出一个 InterruptedException
,这是一个特殊的异常,表示线程在被中断的过程中被打断了。
抛出 InterruptedException
时,线程的中断标志会被清除,意味着线程已经知道中断发生了,但它需要处理这个异常,处理完成后,线程可以检查其中断标志,决定如何继续运行或者是否终止。
具体Demo如上2中所示
4 Object类的 wait,notify 和 notifyAll 方法的目的是什么 ?
Object
类的 wait
、notify
和 notifyAll
方法用于线程间的协调和通信,这些方法通常在多线程编程中用于控制线程的执行顺序。
wait
方法使得调用它的线程进入等待状态,直到其他线程调用了 notify
或 notifyAll
方法,这个等待过程是有条件的,通常在线程需要等待某种条件发生时使用。使用 wait
方法的线程会释放它所持有的锁,从而允许其他线程获得这个锁并执行其操作。
notify
方法会唤醒在对象的监视器上等待的一个线程。如果有多个线程在等待同一个对象的监视器,notify
只会唤醒其中一个线程,但无法保证具体是哪一个线程;如果多个线程都在等待,则唤醒哪个线程是不确定的。
notifyAll
方法则会唤醒在对象的监视器上等待的所有线程。这意味着所有等待的线程都会被唤醒,然后争夺监视器的控制权,如果有多个线程在等待,则它们都会被唤醒,接下来所有被唤醒的线程会尝试重新获得锁,并继续执行。
展示了这些方法如何在实际应用中协作:
public class SharedResource {private boolean condition = false;public synchronized void waitForCondition() {while (!condition) {try {// 进入等待状态,直到 condition 为 truewait();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}// 条件满足后继续执行System.out.println("Condition met, proceeding...");}public synchronized void setConditionTrue() {condition = true;// 通知等待中的线程条件已经满足notifyAll();}
}public class Example {public static void main(String[] args) {SharedResource resource = new SharedResource();// 创建两个线程,它们将等待条件的变化Thread waiter1 = new Thread(() -> resource.waitForCondition());Thread waiter2 = new Thread(() -> resource.waitForCondition());waiter1.start();waiter2.start();try {// 主线程等待一段时间,然后设置条件为 trueThread.sleep(1000);resource.setConditionTrue();} catch (InterruptedException e) {e.printStackTrace();}}
}
通过这种方式,可以实现线程之间的协调,使得一个线程可以通知其他线程某些条件已经发生,从而提高多线程程序的效率和协调性。
不要等待机会,而要创造机会