首页 > 其他分享 >Thread的方法介绍sleep、join、yield、wait、notify、notifyAll

Thread的方法介绍sleep、join、yield、wait、notify、notifyAll

时间:2024-01-10 10:59:39浏览次数:37  
标签:释放 join Thread 线程 notify new CPU wait

本文转载自:https://zhuanlan.zhihu.com/p/665014094

 

一、sleep方法(线程锁)

线程释放CPU进入休眠,但不会释放锁(synchronized),释放CPU,不释放锁

这里面有个比较经典的用法,代码中循环太快,导致年轻代的GC频繁或者GC时间久,可以通过Thread.sleep(0)释放CPU,让GC线程去执行回收

经典用法:线程批任务导致cpu占比很高,通过Thread.sleep(0)可以降低CPU占比

二、yield方法(很少用,线程锁)

很少使用,表示当前线程愿意让出CPU执行器的当前使用权,释放CPU,不释放锁,但是调度器可以自由忽略这个提示。

Yield是一种让多线程的执行进度 尽可能一致的方案,比如有4个线程同时执行一样的算法,但是只有两个线程能同时运行,通过Yield,可以让4个线程尽可能在差不多的时间完成

Thread.yield()某种程度上效果等同于Thread.sleep(0)

三、join方法,控制多个线程的执行顺序(线程锁)

常用操作:线程B等线程A执行完成之后再执行,join底层调用的是wait(),会释放CPU,释放线程锁,不会释放对象锁。

 1 private static void demo2() {  
 2     Thread A = new Thread(new Runnable() {  
 3         @Override  
 4         public void run() {  
 5             printNumber("A");  
 6         }  
 7     });  
 8     Thread B = new Thread(new Runnable() {  
 9         @Override  
10         public void run() {  
11             System.out.println("B 开始等待 A");  
12             try {  
13                 A.join();  
14             } catch (InterruptedException e) {  
15                 e.printStackTrace();  
16             }  
17             printNumber("B");  
18         }  
19     });  
20     B.start();  
21     A.start();  
22 }  
23 
24 -- 执行效果
25 B 开始等待 A 
26 A print: 1 
27 A print: 2 
28 A print: 3
29 B print: 1 
30 B print: 2 
31 B print: 3

 

四、wait()和notify()以及notifyAll() (对象锁)

常用操作:两个线程按照指定方式有序交叉运行,wait会释放synchronized锁,释放CPU

经典用法:dubbo底层 调用netty实现RPC调用,dubbo线程调用netty线程之后,进入wait等待状态,netty线程拿到RPC结果后通过notify对dubbo线程进行唤醒

 1 private static void demo3() {  
 2     Object lock = new Object();  
 3     Thread A = new Thread(new Runnable() {  
 4         @Override  
 5         public void run() {  
 6             synchronized (lock) {  
 7                 System.out.println("A 1");  
 8                 try {  
 9                     lock.wait();  
10                 } catch (InterruptedException e) {  
11                     e.printStackTrace();  
12                 }  
13                 System.out.println("A 2");  
14                 System.out.println("A 3");  
15             }  
16         }  
17     });  
18     Thread B = new Thread(new Runnable() {  
19         @Override  
20         public void run() {  
21             synchronized (lock) {  
22                 System.out.println("B 1");  
23                 System.out.println("B 2");  
24                 System.out.println("B 3");  
25                 lock.notify();  
26             }  
27         }  
28     });  
29 
30     A.start();  
31     B.start();  
32 }  
33 
34 -- 输出结果
35 A 1 
36 B 1 
37 B 2 
38 B 3 
39 A 2 
40 A 3

 

wait 和 notify 这个为什么要在 synchronized 代码块中?

线程间传递参数用。

Synchronized 同步关键字可以实现一个互斥条件,通过共享变量来实现多个线程通信的场景里面,参与通信的线程必须要竞争到这个共享变量的锁资源,才有资格对共享变量做修改,修改完成后就释放锁,那么其他的线程就可以再次来竞争同一个共享变量的锁来获取修改后的数据,从而完成线程之前的通信。

五、线程锁和对象锁

对象锁的作用是为了方便多个线程之间交互用,比如线程间参数传递,线程间按指定顺序执行,线程重入,程序员可以根据需要,灵活的控制线程之间的交互

而线程锁比较简单,就是只能控制自己,让自己更CPU玩,无法做到复杂的线程之间的交互

标签:释放,join,Thread,线程,notify,new,CPU,wait
From: https://www.cnblogs.com/zhncnblogs/p/17956021

相关文章

  • Java Thread Dump文件分析
    分析线程转储对于确定多线程进程中的问题非常有用,可以通过可视化单个线程转储的状态来解决死锁、锁争用和过多的CPU利用率等问题。通过在分析线程转储后纠正每个线程的状态,可以实现应用程序的最大吞吐量。例如,假设一个进程占用了大量CPU,我们可以找出是否有哪个线程占用CPU最多。如......
  • 【设计模式】单例模式——利用ThreadLocal或CAS实现单线程内部的单例模式
    很多时候我们并不需要一个类创建的对象是全局唯一的,只需要保证在单个线程内是唯一的、线程安全的就可以。为了实现单线程内部的单例,我们可以用ThreadLocal或CAS实现。利用ThreadLocal实现先看代码:publicclassThreadLocalSingleton{privatestaticfinalThreadLocal<Thread......
  • oracle如何进行复杂的join查询
    在Oracle数据库中,进行复杂的JOIN查询涉及多个表之间的连接,可以使用JOIN子句来实现。以下是一些示例,展示如何在Oracle中执行复杂的JOIN查询:1.内连接(INNERJOIN):SELECTemployees.employee_id,employees.employee_name,departments.department_nameFROMemployeesINNERJOIN......
  • 技术大拿私房课:掌握Task、Thread、ThreadPool的终极秘籍!
    大家好,我是小米!在这个充满技术和创新的时代,作为一名喜欢分享的技术探索者,我想和大家聊一聊一些在社招面试中常常被提到的热门话题——task、thread、threadpool。这是一组关于并发编程的核心问题,也是我们在日常工作中不可避免要面对的挑战。Task是什么?首先,让我们从Task开始说起。在......
  • QProgressDialog用法及结合QThread用法,四种线程使用
    1QProgressDialog概述QProgressDialog类提供耗时操作的进度条。进度对话框用于向用户指示操作将花费多长时间,并演示应用程序没有冻结。此外,QPorgressDialog还可以给用户一个中止操作的机会。进度对话框的一个常见问题是很难知道何时使用它们;操作在不同的硬件上花费不同的时间......
  • ThreadLocal:你不知道的优化技巧,Android开发者都在用
    引言在Android开发中,多线程是一个常见的话题。为了有效地处理多线程的并发问题,Android提供了一些工具和机制。其中,ThreadLocal是一个强大的工具,它可以使得每个线程都拥有自己独立的变量副本,从而避免了线程安全问题。本文将深入探讨Android中的ThreadLocal原理及其使用技巧,帮助你更......
  • STM32F103C8T6移植RT_Thread nane过程记录
    一、创建基于官方库的裸机工程(这教程很多,每个人创建的工程风格也不一样,就不多赘述了) 二、下载RT-ThreadNano源代码(https://github.com/RT-Thread/rtthread-nano/archive/refs/heads/master.zip)  三、RT-ThreadNano源码目录结构 四、将核心文件添加到裸机工程中 ......
  • ThreadPoolExecutor源码学习
    Java构建线程的方式集成Thread实现Runnable实现CallAble线程池方式Java提供了Executors创建(不推荐,不方便进行控制)推荐手动创建线程池ThreadPoolExecutor。ThreadPoolExecutor参数intcorePoolSize核心线程数intmaximumPoolSize最大线程数,最大减核心是非核心线程......
  • Java线程池ThreadPoolExecutor源码解析
    Java线程池ThreadPoolExecutor源码解析1.ThreadPoolExecutor的构造实现以jdk8为准,常说线程池有七大参数,通常而言,有四个参数是比较重要的publicThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,lon......
  • 面试官:MySQL 到底是 join 性能好,还是 in 一下更快呢?被问懵逼了…
    来源:https://juejin.cn/post/7169567387527282701先总结:数据量小的时候,用join更划算数据量大的时候,join的成本更高,但相对来说join的速度会更快数据量过大的时候,in的数据量过多,会有无法执行SQL的问题,待解决事情是这样的,去年入职的新公司,之后在代码review的时候被提出说,不要......