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

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

相关文章

Redis的Zset类型及相关命令详细讲解

《Redis的Zset类型及相关命令详细讲解》:本文主要介绍Redis的Zset类型及相关命令的相关资料,有序集合Zset是一种Redis数据结构,它类似于集合Set,但每个元素都有一个关联的分数... 目录Zset简介ZADDZCARDZCOUNTZRANGEZREVRANGEZRANGEBYSCOREZ

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

关于Maven生命周期相关命令演示

《关于Maven生命周期相关命令演示》Maven的生命周期分为Clean、Default和Site三个主要阶段,每个阶段包含多个关键步骤,如清理、编译、测试、打包等,通过执行相应的Maven命令,可以... 目录1. Maven 生命周期概述1.1 Clean Lifecycle1.2 Default Li

numpy求解线性代数相关问题

《numpy求解线性代数相关问题》本文主要介绍了numpy求解线性代数相关问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 在numpy中有numpy.array类型和numpy.mat类型,前者是数组类型,后者是矩阵类型。数组

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

Redis的Hash类型及相关命令小结

《Redis的Hash类型及相关命令小结》edisHash是一种数据结构,用于存储字段和值的映射关系,本文就来介绍一下Redis的Hash类型及相关命令小结,具有一定的参考价值,感兴趣的可以了解一下... 目录HSETHGETHEXISTSHDELHKEYSHVALSHGETALLHMGETHLENHSET

C语言线程池的常见实现方式详解

《C语言线程池的常见实现方式详解》本文介绍了如何使用C语言实现一个基本的线程池,线程池的实现包括工作线程、任务队列、任务调度、线程池的初始化、任务添加、销毁等步骤,感兴趣的朋友跟随小编一起看看吧... 目录1. 线程池的基本结构2. 线程池的实现步骤3. 线程池的核心数据结构4. 线程池的详细实现4.1 初

Java子线程无法获取Attributes的解决方法(最新推荐)

《Java子线程无法获取Attributes的解决方法(最新推荐)》在Java多线程编程中,子线程无法直接获取主线程设置的Attributes是一个常见问题,本文探讨了这一问题的原因,并提供了两种解决... 目录一、问题原因二、解决方案1. 直接传递数据2. 使用ThreadLocal(适用于线程独立数据)

python中的与时间相关的模块应用场景分析

《python中的与时间相关的模块应用场景分析》本文介绍了Python中与时间相关的几个重要模块:`time`、`datetime`、`calendar`、`timeit`、`pytz`和`dateu... 目录1. time 模块2. datetime 模块3. calendar 模块4. timeit

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert