2023-06-14  阅读(55)
原文作者:求和的小熊猫 原文地址:https://blog.csdn.net/qq_38219153/article/details/108470258

中断线程

Java 线程使用一种机制来表想要终止他。这个中断机制依靠线程对象来检查当前线程是否需要中断,同时对象也可以决定是否响应中断请求。

Java 中断线程的方法为 Thread.interrupt(),该方法会读取中断标志位并重置中断标志位。同时我们可以使用 Thread.isInterrupted() 方法来判断线程是否收到中断信号。

在调用 interrupt 方法时,如果线程处于 WAITING 状态或者 TIMED_WAITING 状态,则会抛出一个 InterruptedException 异常。
【示例】

待中断的线程

该线程主要负责不断答应质数

    public class PrimeGenerator extends Thread {
    	@Override
    	public void run() {
    		long number = 1L;
    		while (true) {
    			if(isPrime(number)) {
    				System.out.printf("Number %d is Prime\n", number);
    			}
    			if(isInterrupted()) {
    				System.out.println("The Prime Generator has been Interrupted\n");
    				break;
    			}
    			number++;
    		}
    	}
    	
    	private boolean isPrime(long number) {
    		if(number <=2) {
    			return true;
    		}
    		for(long i=2; i<number; i++) {
    			if((number %i)==0) {
    				return false;
    			}
    		}
    		return true;
    	}
    }

Main 方法

调用线程并中断线程

    public class Main {
    
    	public static void main(String[] args) {
    		Thread task = new PrimeGenerator();
    		task.start();
    		try {
    			Thread.sleep(5000);
    		}catch(InterruptedException e) {
    			e.printStackTrace();
    		}
    		task.interrupt();
    		System.out.printf("Main: Status of the Thread: %s\n", task.getState());
    		System.out.printf("Main: IsInterrupted: %s\n", task.isInterrupted());
    		System.out.printf("Main: Is Alive %s\n", task.isAlive());
    	}
    
    }

PS: 线程在调用 interrupt 方法时会强制唤醒线程

线程休眠

线程休眠有两种方式,一种是 Thread.sleep() 方法,另一种是使用 TimeUnit 枚举类的 sleep() 方法。

两种休眠方法的区别:

  • Thread.sleep() :接受一个long 类型的变量,时间单位为毫秒
  • TimeUnit : 可以自动设定时间单位。

【示例】

    TimeUnit.SECONDS.sleeep(5);

线程等待与唤醒

线程的等待的常用函数为 Object.wait() 而线程唤醒的常用函数为 Object.notiyfy()Object.notifyall()

wait() 方法会释放当前所占有的锁,让线程进入到重新请求锁的状态来实现阻塞
notify()notifyAll() 会通知相应的线程去重新获得锁。

为什么线程的等待与唤醒会放在 Object 类中?

要想更好的理解这个问题可以看以下代码

    synchronized(obj){
        ...
        obj.wait();
        ...
    }
    
    
    
    synchronized(obj){
        ...
        obj.notify();
        ...
    }

当我们在执行过程中,线程已经不满足继续执行的条件导致阻塞,那么我么需要释放相应的资源,但同时我们又不能破坏线程操作的原子性,那么这个时候我们只需要释放对象所持有的锁即可。由于 synchronized 能够锁住任何的对象,因此为了能够保证顺利释放对象,因此 notify 和 wait 便放在了 Object 对象中。

PS: wait 和 notify 必须和 synchronized 关键字一起使用,因为 wait 释放锁的前提是加锁,而 notify 的重新竞争也是在加锁的基础进行的。

线程礼让

线程礼让的方法为 Thread.yield() 方法时暂停当前正在执行的线程,也可理解为线程让出当前的执行时间片给其他线程。在礼让过程中不会释放锁。

等待线程结束

在某些情况下,我们需要某个线程等待其他线程执行结束后再继续执行时,我们可以使用 Thread.join() 方法。

join 方法类似于 wait 方法,会释放锁,只不过 join 方法释放的是正在执行的 thread 对象的锁。

方法掉用时线程状态转换图

202306142125573451.png


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文