线程休眠、线程让步、线程优先级相关内容学习笔记

2024-01-11 17:36

本文主要是介绍线程休眠、线程让步、线程优先级相关内容学习笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

    1、线程休眠

    (1)sleep()

   

        如果需要让当前正在执行的线程暂停一段时间,并进入阻塞状态(Timed_Waiting),则可以通过调用Thread类的静态sleep()方法来实现。

   

        static void sleep(long millis):让当前正在执行的线程暂停millis毫秒,并进入阻塞状态,该方法受到系统计时器和线程调度器的精度与准确度的影响。

        static void sleep(long millis,int nanos):让当前正在执行的线程暂停millis毫秒加nanos毫微秒,并进入阻塞状态,该方法受到系统计时器和线程调度器的精度与准确度的影响。

        当前线程调用 sleep()方法进入阻塞状态后,在其睡眠时间段内,该线程不会获得执行的机会,即使系统中没有其他可执行的线程,处于sleep()中的线程也不会执行,因此sleep()方法常用来暂停程序的执行。

/**

 * sleep()方法练习

   */

   public class SleepDemo1 {

   public static void main(String[] args) {

       Thread t1 = new Thread(()->{

          while(true){

               System.out.println(true);

               try {

                   Thread.sleep(3000);

               } catch (InterruptedException e) {

                   throw new RuntimeException(e);

               }

          }

       });

       //t1不调用start()方法 只调用run()方法时

       //此时只有main线程运行 调用sleep()休眠的是mian线程

       t1.run();

       System.out.println("main线程休眠");

   }

   }

/**

 * sleep()方法练习

   */

   public class SleepDemo2 {

   public static void main(String[] args) throws InterruptedException {

       Thread t2 = new Thread(()->{

           while(true){

               System.out.println(true);

               try {

                   //t2线程休眠 无法在休眠时间段内唤醒线程

                   Thread.sleep(1000);

               } catch (InterruptedException e) {

                   throw new RuntimeException(e);

               }

           }

       });

       t2.start();

       //休眠主线程 确保t2线程执行

       TimeUnit.SECONDS.sleep(3);

       //sleep()休眠后 t2线程的状态为TIME_WAITING

       System.out.println(t2.getState());//TIMED_WAITING

   }

   }

/**

 * sleep()方法练习

   */

   public class SleepDemo3 {

   public static void main(String[] args) throws InterruptedException {

       Thread t3 = new Thread(()->{

           while(true){

               System.out.println(true);

           }

       });

       t3.start();

       //注意 sleep()是类方法 能使用创建对象的方式调用,但是不会有休眠效果,所以不能使用这种方式调用sleep()方法

       t3.sleep(1000);

       //休眠主线程 确保t2线程执行

       TimeUnit.SECONDS.sleep(3);

       //此时,t2线程不会被休眠

   }

   }

/**

 * Interrupt()方法

   */

   public class InterruptedDemo {

   public static void main(String[] args) {

       Thread t4 = new Thread(()->{

           while (true){

               System.out.println(true);

           }

       });

       t4.start();

       //调用interrupt()方法无法中断线程

       //只能采用先标记线程中断

       //然后通过Thread.interrupted();判断线程状态是否为中断状态

       //若为true则通过抛异常的方式中断程序

       t4.interrupt();

   }

   }

   (2) LockSupport类

   

    LockSupport是JUC提供的一个线程阻塞与唤醒的工具类,该工具类可以让线程在任意位置阻塞和唤醒,其所有的方法都是静态方法。

/**

 * park()方法练习

   */

   public class LockSupportDemo1 {

   public static void main(String[] args) throws InterruptedException {

       Thread t1 = new Thread(()->{

           System.out.println("t1线程开始休眠");

           //无休止休眠 t1线程为阻塞态 为Waiting

           LockSupport.park();

           System.out.println("t1线程结束休眠");

       });

       //启动线程t1

       t1.start();

       //休眠主线程,让线程t1能顺利执行

       TimeUnit.SECONDS.sleep(3);

       System.out.println(t1.getState());//Waiting

   }

   }

/**

 * unpark()方法练习

   */

   public class LockSupportDemo2 {

   public static void main(String[] args) throws InterruptedException {

       Thread t2 = new Thread(()->{

           System.out.println("t1线程开始休眠");

           //休眠指定的时间 休眠后可以在休眠时间段内重新被唤醒 比较灵活

           LockSupport.parkNanos(10000000000L);

           System.out.println("t1线程结束休眠");

       });

       //启动线程t2

       t2.start();

       //休眠主线程,让线程t2能顺利执行

       TimeUnit.SECONDS.sleep(3);

       LockSupport.unpark(t2);

       System.out.println(t2.getState());//Time_Waiting(不定)

       System.out.println("线程被唤醒");

       System.out.println(t2.getState());//TERMINATED

   }

   }

   当调用park()方法时,会让线程进入WAITING状态,调用parkNanos(long nanos)方法时,线程会进入TIMED_WAITING状态

/**

 * unpark()方法练习

   */

   public class LockSupportDemo2 {

   public static void main(String[] args) throws InterruptedException {

       Thread t2 = new Thread(()->{

           System.out.println("t1线程开始休眠");

           //休眠指定的时间 休眠后可以在休眠时间段内重新被唤醒 比较灵活

           LockSupport.parkNanos(10000000000L);

           System.out.println("t1线程结束休眠");

       });

       //启动线程t2

       t2.start();

       //休眠主线程,让线程t2能顺利执行

       TimeUnit.SECONDS.sleep(3);

       LockSupport.unpark(t2);

       System.out.println(t2.getState());//Time_Waiting(不定)

       System.out.println("线程被唤醒");

       System.out.println(t2.getState());//TERMINATED

   }

   }

   LockSupport.park()和Thread.sleep()的区别:

   1、Thread.sleep()无法从外部唤醒。只能自己醒过来;而被LockSupport.park()方法阻塞的线程可以通过调用LockSupport.unpark()方法去唤醒。

   2、被Thread.sleep()、LockSupport.park()方法所阻塞的线程有一个特点,当被阻塞线程的Thread.interrupt()方法调用时,被阻塞线程的中断标志将被设置,该线程将被唤醒。不同的是,二者对中断信号的响应方式不同:LockSuppport.park()方式不会抛出InterruptedExcepton异常,仅仅设置了线程的中断标志;而Thread.sleep()方法会抛出InterruptedException异常

   3、与Thread.sleep()相比,调用LockSupport.park()更能精准、更加灵活地阻塞、唤醒指定线程。

   2、线程让步

   yield()方法是一个和 sleep()方法有点相似的方法,它也是 Thread 类提供的一个静态方法,它也可以让当前正在执行的线程暂停,但它不会阻塞该线程,它只是将该线程转入就绪状态。

   yield()只是让当前线程暂停一下,让系统的线程调度器重新调度一次,线程调度器会从线程就绪队列里获取一个线程优先级高的线程,当然完全可能的情况是:当某个线程调用了yield()方法暂停之后,线程调度器又将其调度出来重新执行。

   当某个线程调用了yield()方法暂停之后,只有优先级与当前线程相同,或者优先级比当前线程更高的处于就绪状态的线程才会获得执行的机会。下面程序使用yield()方法来让当前正在执行的线程暂停。

/**

 * yield()方法练习

   */

   public class YieldDemo {

   public static void main(String[] args) {

       Thread t1 = new Thread(()->{

           for (int i = 1; i < 30; i++) {

               System.out.println(Thread.currentThread().getName()+"=============="+i);

               if(i%10==0){

                   //调用yield方法让t1线程暂停

                   Thread.yield();

               }

           }

       },"t1");

       Thread t2 = new Thread(()->{

           for (int i = 0; i < 30; i++) {

               System.out.println(Thread.currentThread().getName()+">>>"+i);

           }

       },"t2");

       //yield之后,有可能原来执行的线程继续获得执行的机会

       //为t1线程设置优先级

       t1.setPriority(10);

       //启动t1线程

       t1.start();

       //为t2线程设置优先级

       t2.setPriority(1);

       //启动t2线程

       t2.start();

       //优先级大的线程不一定先执行,而是执行概率大

       for (int i = 0; i < 30; i++) {

           System.out.println(Thread.currentThread().getName()+">>>"+i);

       }

   }

   }

   3、线程优先级

   每个线程执行时都具有一定的优先级,优先级高的线程获得较多的执行机会,而优先级低的线程则获得较少的执行机会。每个线程默认的优先级都与创建它的父线程的优先级相同,在默认情况下,main线程具有普通优先级,由main线程创建的子线程也具有普通优先级。

   Thread类提供了setPriority(int newPriority)、getPriority()方法来设置和返回指定线程的优先级,其中setPriority()方法的参数可以是一个整数,范围是1~10之间,也可以使用Thread类的如下3个静态常量。

   MAX_PRIORITY:其值是10。

   MIN_PRIORITY:其值是1。

   NORM_PRIORITY:其值是5。

/**

 * 优先级练习

   */

   public class PriorityDemo {

   public static void main(String[] args) throws InterruptedException {

       //定义存放线程的数组

       MyThread[] myThreads = new MyThread[10];

       int length = myThreads.length;

       //优先级为1<-->10 循环需要从1开始

       for (int i = 1; i <=length; i++) {

           //创建线程

           myThreads[i-1] = new MyThread();

           //分别创建线程优先级

           myThreads[i-1].setPriority(i);

           //启动线程

           myThreads[i-1].start();

       }

       //休眠主线程 让创建的线程得以执行

       TimeUnit.SECONDS.sleep(3);

       for (int i = 0; i < length; i++) {

           //停止线程

           myThreads[i].stop();

       }

   }

   }

   优先级的继承

   /**

 * 优先级练习2

   */

   public class PriorityDemo2 {

   public static void main(String[] args) {

       Thread thread = new Thread(()->{

           System.out.println("线程thread执行");

       },"thread");

       Thread main = Thread.currentThread();

       System.out.println(main.getState());

       System.out.println(main.getName()+"线程的优先级:"+main.getPriority());

       //在main线程中创建thread线程,thread线程的优先级与main线程一致

       thread.start();

       System.out.println(thread.getName()+"线程的优先级:"+thread.getPriority());

   }

   }


 

这篇关于线程休眠、线程让步、线程优先级相关内容学习笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/595160

相关文章

Java中如何正确的停掉线程

《Java中如何正确的停掉线程》Java通过interrupt()通知线程停止而非强制,确保线程自主处理中断,避免数据损坏,线程池的shutdown()等待任务完成,shutdownNow()强制中断... 目录为什么不强制停止为什么 Java 不提供强制停止线程的能力呢?如何用interrupt停止线程s

python 线程池顺序执行的方法实现

《python线程池顺序执行的方法实现》在Python中,线程池默认是并发执行任务的,但若需要实现任务的顺序执行,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋... 目录方案一:强制单线程(伪顺序执行)方案二:按提交顺序获取结果方案三:任务间依赖控制方案四:队列顺序消

Java使用正则提取字符串中的内容的详细步骤

《Java使用正则提取字符串中的内容的详细步骤》:本文主要介绍Java中使用正则表达式提取字符串内容的方法,通过Pattern和Matcher类实现,涵盖编译正则、查找匹配、分组捕获、数字与邮箱提... 目录1. 基础流程2. 关键方法说明3. 常见场景示例场景1:提取所有数字场景2:提取邮箱地址4. 高级

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

C#高效实现Word文档内容查找与替换的6种方法

《C#高效实现Word文档内容查找与替换的6种方法》在日常文档处理工作中,尤其是面对大型Word文档时,手动查找、替换文本往往既耗时又容易出错,本文整理了C#查找与替换Word内容的6种方法,大家可以... 目录环境准备方法一:查找文本并替换为新文本方法二:使用正则表达式查找并替换文本方法三:将文本替换为图

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

Linux从文件中提取特定内容的实用技巧分享

《Linux从文件中提取特定内容的实用技巧分享》在日常数据处理和配置文件管理中,我们经常需要从大型文件中提取特定内容,本文介绍的提取特定行技术正是这些高级操作的基础,以提取含有1的简单需求为例,我们可... 目录引言1、方法一:使用 grep 命令1.1 grep 命令基础1.2 命令详解1.3 高级用法2

SpringBoot实现虚拟线程的方案

《SpringBoot实现虚拟线程的方案》Java19引入虚拟线程,本文就来介绍一下SpringBoot实现虚拟线程的方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录什么是虚拟线程虚拟线程和普通线程的区别SpringBoot使用虚拟线程配置@Async性能对比H

在Java中实现线程之间的数据共享的几种方式总结

《在Java中实现线程之间的数据共享的几种方式总结》在Java中实现线程间数据共享是并发编程的核心需求,但需要谨慎处理同步问题以避免竞态条件,本文通过代码示例给大家介绍了几种主要实现方式及其最佳实践,... 目录1. 共享变量与同步机制2. 轻量级通信机制3. 线程安全容器4. 线程局部变量(ThreadL

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为