热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JUC并发编程——线程的基本方法使用

目录一、线程名称设置和获取二、线程的sleep()三、线程的interrupt四、join()五、yield()六、wait(),notify(),notifyAll(

目录

一、线程名称设置和获取

二、线程的sleep()

三、线程的interrupt

四、join()

五、yield()

六、wait(),notify(),notifyAll()



一、线程名称设置和获取

1、线程名称一般在线程启动前设置,但也允许为正在运行的线程设置名称。在实际开发中,在使用多线程开发时,一定要自定义线程名称,偏于查找日志。

2、线程允许使用同样的名字,但应该尽量避免。

3、如果线程没有命名,系统会自动为线程设置名称。例如Thread-0,Thread-1。在SpringBoot中http-nio-端口号-exec-1,http-nio-端口号-exec-2。

线程命名

package com.xiaojie.juc.thread.base;/*** @author xiaojie* @version 1.0* @description: 线程命名和获取名称* @date 2021/12/17 22:54*/
public class ThreadNameDemo {public static void main(String[] args) {A a = new A();new Thread(a,"mythraed-a").start();new Thread(a,"mythraed-b").start();}static class A implements Runnable{@Overridepublic void run() {//获取线程名称System.out.println("当前线程的名称是>>>>>>>>:"+Thread.currentThread().getName());}}
}

线程池命名

package com.xiaojie.juc.thread.base;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;/*** @author xiaojie* @version 1.0* @description: 线程池命名* @date 2021/12/17 23:09*/
public class ThreadPoolNameDemo {private static final AtomicInteger threadNumber &#61; new AtomicInteger(1);private static final String MYTHREAD_POOL_GROUP &#61; "mythread-pool-group-thread-";public static void main(String[] args) {ExecutorService executorService &#61; Executors.newFixedThreadPool(3, r -> new Thread(new ThreadGroup(""), r,MYTHREAD_POOL_GROUP &#43; threadNumber.getAndIncrement(),0));for (int i &#61; 0; i <10; i&#43;&#43;) {executorService.execute(() -> System.out.println("当前线程名称>>>>>>>>>:" &#43; Thread.currentThread().getName()));}//关闭线程池executorService.shutdown();}
}

二、线程的sleep()

package com.xiaojie.juc.thread.base;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/*** &#64;author xiaojie* &#64;version 1.0* &#64;description: 线程sleep方法* &#64;date 2021/12/17 23:46*/
public class ThreadSleepDemo {public static void main(String[] args) {ExecutorService executorService &#61; Executors.newFixedThreadPool(3);for (int i &#61; 0; i <10; i&#43;&#43;) {executorService.execute(() -> {try {if (Thread.currentThread().isInterrupted()) {System.out.println("Thread is Interrupted");}//一定要捕捉InterruptedException异常Thread.sleep(1000);} catch (InterruptedException e) {}System.out.println(Thread.currentThread().getName());});}//关闭线程池executorService.shutdown();}
}

sleep的作用是让目前正在执行的线程休眠&#xff0c;让CPU去执行其他任务&#xff0c;使线程从运行状态进去阻塞状态。当线程睡眠时间满后&#xff0c;线程并不一定是立刻马上开始执行&#xff0c;因为CPU可能正在执行其他任务&#xff0c;线程进入就绪状态&#xff0c;等待CPU分配时间片后才能执行。

三、线程的interrupt

Thread提供了stop()&#xff0c;但是是个过时方法&#xff0c;不推荐使用。stop()方法是强制中断线程&#xff0c;不管当前线程是否正在运行&#xff0c;有可能导致当前线程持有当前锁&#xff0c;强行中断后可能不会释放锁。interrupt()并不是用来中断一个线程&#xff0c;而是将线程设置为中断状态。

1、如果执行interrupt()时&#xff0c;当前线程处于阻塞状态&#xff08;wait(),sleep(),join()&#xff09;时&#xff0c;线程会立刻退出阻塞&#xff0c;抛出InterruptedException异常。

2、如果调用interrupt()时&#xff0c;线程处于运行状态&#xff0c;线程不受任何影响&#xff0c;只是会将中断标识设置为true,可以调用isInterrupted(),判断是否中断。

package com.xiaojie.juc.thread.base;/*** &#64;author xiaojie* &#64;version 1.0* &#64;description: 线程中断* &#64;date 2021/12/18 0:12*/
public class InterruptDemo {public static void main(String[] args) {A a &#61; new A();a.start();}static class A extends Thread {&#64;Overridepublic void run() {//手动中断线程Thread.currentThread().interrupt();try {while (true) {if (Thread.currentThread().isInterrupted()) {System.out.println("线程中断了");break;}}Thread.sleep(3000);System.out.println(Thread.currentThread().getName());} catch (InterruptedException e) {e.printStackTrace();System.out.println("线程中断了。。。。。when sleep");}}}
}

四、join()

 线程A在运行时&#xff0c;线程Bjoin(),之后&#xff0c;线程A会等待直到线程B运行完之后&#xff0c;才开始执行。如果线程B无限制运行&#xff0c;线程A可以设置等待时长join(1000)单位是毫秒。

package com.xiaojie.juc.thread.base;/*** &#64;author xiaojie* &#64;version 1.0* &#64;description:线程join模拟* &#64;date 2021/12/18 0:45*/
public class ThreadJoinDemo {public static void main(String[] args) {new A().start();}static class A extends Thread {&#64;Overridepublic void run() {try {B b &#61; new B();b.start();b.join();//B线程join之后&#xff0c;A线程需要等待B运行完之后才执行} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程A执行任务。。。。。。。");}}static class B extends Thread {&#64;Overridepublic void run() {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程B执行任务。。。。。。。");}}
}

五、yield()

yield的作用是让正在执行的线程让出CPU的执行权限&#xff0c;使得CPU可以去执行其他任务。从线程状态来看&#xff0c;线程从运行变为就绪状态。线程在yield()方法之后&#xff0c;线程放弃和重占CPU是不确定的&#xff0c;可能是刚刚放弃CPU&#xff0c;马上又获得CPU执行权。yield不会阻塞线程&#xff0c;只会让当前线程暂停一下&#xff0c;让系统线程调度器重新调度一次。

package com.xiaojie.juc.thread.base;/*** &#64;author xiaojie* &#64;version 1.0* &#64;description: Yield实例* &#64;date 2021/12/18 1:13*/
public class ThreadYieldDemo {public static void main(String[] args) {Thread threadA &#61; new Thread(new A());threadA.setPriority(1);threadA.setName("threadA ");Thread threadB &#61; new Thread(new B());threadB.setName("threadB ");threadA.start();threadB.start();}static class A implements Runnable {&#64;Overridepublic void run() {//暂停一下,重新调度线程Thread.yield();System.out.println(Thread.currentThread().getName());}}static class B implements Runnable {&#64;Overridepublic void run() {System.out.println(Thread.currentThread().getName());}}
}

六、wait(),notify(),notifyAll()

这三个方法不是Thread独有的方法&#xff0c;是Object的方法&#xff01;&#xff01;&#xff01;

当一个对象实例调用了wait()方法后&#xff0c;当前线程会在这个对象上等待。直到其他线程调用这个实例的notify(),或者notifyAll()方法后才会唤醒。调用了wait()方法后&#xff0c;该线程就会进入该实例的等待队列&#xff0c;如果队列中有多个线程&#xff0c;notify()只会随机的唤醒一个线程。这个选择是不公平的&#xff0c;不是先等待的就会先唤醒。notifyAll(),是唤醒所有的等待线程。而且这些方法只能在synchronized代码块中使用。wait&#xff08;&#xff09;和sleep()都会让线程等待&#xff0c;但是wait()方法会释放目标对象的锁&#xff0c;而sleep()方法不会释放任何资源。

package com.xiaojie.juc.thread.base;/*** &#64;author xiaojie* &#64;version 1.0* &#64;description: wait demo* &#64;date 2021/12/18 1:43*/
public class ThreadWaitDemo {private static final Object obj &#61; new Object();public static void main(String[] args) {new Thread(new A()).start();new Thread(new B()).start();}static class A implements Runnable {&#64;Overridepublic void run() {synchronized (obj) {System.out.println("线程A开始等待。。。。。。");try {obj.wait();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程A等待结束。。。。。。");System.out.println("线程A开始执行。。。。。。");}}}static class B implements Runnable {&#64;Overridepublic void run() {synchronized (obj) {try {obj.notify();Thread.sleep(2000);System.out.println("线程B运行。。。。。");} catch (InterruptedException e) {e.printStackTrace();}}}}
}

参考&#xff1a;《JAVA高并发核心编程&#xff08;卷2&#xff09;&#xff1a;多线程、锁、JMM、JUC、高并发设计》-尼恩编著


推荐阅读
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • 实体映射最强工具类:MapStruct真香 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • Scala 实现 UTF-8 编码属性文件读取与克隆
    本文介绍如何使用 Scala 以 UTF-8 编码方式读取属性文件,并实现属性文件的克隆功能。通过这种方式,可以确保配置文件在多线程环境下的一致性和高效性。 ... [详细]
  • 解决JAX-WS动态客户端工厂弃用问题并迁移到XFire
    在处理Java项目中的JAR包冲突时,我们遇到了JaxWsDynamicClientFactory被弃用的问题,并成功将其迁移到org.codehaus.xfire.client。本文详细介绍了这一过程及解决方案。 ... [详细]
  • 本文探讨了领域驱动设计(DDD)的核心概念、应用场景及其实现方式,详细介绍了其在企业级软件开发中的优势和挑战。通过对比事务脚本与领域模型,展示了DDD如何提升系统的可维护性和扩展性。 ... [详细]
  • 深入解析 Spring Security 用户认证机制
    本文将详细介绍 Spring Security 中用户登录认证的核心流程,重点分析 AbstractAuthenticationProcessingFilter 和 AuthenticationManager 的工作原理。通过理解这些组件的实现,读者可以更好地掌握 Spring Security 的认证机制。 ... [详细]
  • Struts与Spring框架的集成指南
    本文详细介绍了如何将Struts和Spring两个流行的Java Web开发框架进行整合,涵盖从环境配置到代码实现的具体步骤。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
  • 本文介绍如何使用布局文件在Android应用中排列多行TextView和Button,使其占据屏幕的特定比例,并提供示例代码以帮助理解和实现。 ... [详细]
  • 深入理解Redis的数据结构与对象系统
    本文详细探讨了Redis中的数据结构和对象系统的实现,包括字符串、列表、集合、哈希表和有序集合等五种核心对象类型,以及它们所使用的底层数据结构。通过分析源码和相关文献,帮助读者更好地理解Redis的设计原理。 ... [详细]
author-avatar
敦恒
招聘!招聘!招聘! 联系方式:56226135/shiziqian@hy9z.com 请优先邮件联系~谢谢!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有