Java多线程

线上系统假死、内存溢出分析常用命令 查询jvm进程占用的cpu,内存 pidstat –p 进程号或者用命令:top –p 进程号   示例: top –p 10461 说明: 系统运行时间和平均负载: top - 11:25:12(当前时间) up 28 days, 42 min(系统已运行时间), 13 users(当前登录用户数),  load average: 0.98, 1.00, 1.02(5分钟,10分... 阅读详情

1、多个生产者与多个消费者时出现“假死”问题
由于有多个消费者的存在,如果释放锁是使用notify(),即随机释放一个对象锁,有可能释放的是一个同类的锁。
场景:

  1. 生产者1线程生产了一条消息,释放一个锁
  2. 生产者1线程再次获得锁马上进入发现已经有数据,进入等待状态
  3. 生产者2线程进入发现已经有数据了,进入等待状态
  4. 消费者2线程运行消费了一条消息,释放一个锁
  5. 消费者2线程再次获得锁,发现没数据,进入等待状态
  6. 消费者1线程运行,发现没数据,进入等待状态
  7. 生产者1线程检测到没数据了,生产一个数据,释放一个锁
  8. 生产者1线程再次进入发现已经有数据,进入等待状态
  9. 生产者2线程进入发现已经有数据,进入等待状态

解决:用notifyAll();释放所有的线程锁

2、 多线程之间的管道通讯(字节流)
两条线程之间使用 PipeInputStream与PipeOutputStream进行数据的交流
使用connect()把输入管道与输出管道连接起来

3、多线程之间的管道通讯(字符流)
两条线程之间使用PipedReader与PipedWriter进行数据的交流
使用connect()把输入管道与输出管道连接起来

4、使用join使线程排队运行,有些类似同步的运行效果,join与synchronized的区别是:join在内部使用wait()方法等待,而synchronized关键字使用的是“对象监控器”

5、ThreadLocal修饰的static变量,可以令各个线程都获取回自己属于自己线程的变量

6、InheritableThreadLocal可以让线程变量的值继承,让子线程获得的值与父线程的一样,并且可以在继承的同时对子线程的值进行修改

7、ReentrantLock实现同步,与synchronized效果一样,ReentrantLock配合Condition可以实现“选择性通知”,而synchronized的wait(),notify(),notifyALL()只能随机通知一个,要么全部通知。使用conditon之前一定要先使用lock,否则会抛出IllegalMonitorStateException异常

8、getHoldCount()、getQueueLength()、getWaitQueueLength()用法
getHoldCount()是查询当前线程保持此锁的个数
getQueueLength()返回正等待获取此锁定的线程估计数
getWaitQueueLength()返回等待与此锁定相关的给定条件Condition的线程估计数

9、hasQueuedThread()、hasQueuedThreads()、hasWaiters()用法
hasQueuedThread()查询指定的线程是否正在等待获取此锁定
hasQueuedThreads()查询是否有线程正在等待获取此锁定
hasWaiters()查询是否有线程正在等待与此锁定有关的condition条件

10、isFair()、isHeldByCurrentThread()、isLocked()用法
isFair()判断是不是公平锁
isHeldByCurrentThread()查询当前线程是否保持此锁定
isLocked()查询此锁定是否由任意线程保持

11、awaitUntil()用法
相当于await(),指定睡眠的时间,期间可以被其它线程唤醒

12、ReentrantReadWriteLock读写锁
“读写”、“写读”、“写写”互斥
“读读”异步非互斥

13、schedule如果执行任务的时间被延时,那么下一次任务的执行时间以上一次任务结束时的时间为参考来计算
scheduleAtFixedRate如果执行任务的时间没有被延时,则下一次执行任务的时间是上一次任务的开始时间加上delay时间
scheduleAtFixedRate如果执行任务的时间被延时,那么下一次任务的执行时间以上一次任务结束时的时间为参考来计算

14、利用DLC双重检查锁来解决“懒汉模式”遇到多线程的问题

15、静态内置类实现单例模式可避免多线程问题

16、序列化与反序列化实现单例模式避免多线程问题,readresolve会自动触发以确保反序列化的对象是原来的那个对象,确保单例

17、ThreadPoolExecutor执行器的处理流程:
(1)当线程池大小小于corePoolSize就新建线程,并处理请求.
(2)当线程池大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去从workQueue中取任务并处理.
(3)当workQueue放不下新入的任务时,新建线程加入线程池,并处理请求,如果池子大小撑到了maximumPoolSize就用RejectedExecutionHandler来做拒绝处理.
(4)另外,当线程池的线程数大于corePoolSize的时候,多余的线程会等待keepAliveTime长的时间,如果无请求可处理就自行销毁.

18、Semaphore类通常用于限制可以访问某些资源(物理或逻辑的)线程数目。acquire获得许可后,许可量减少;release释放许可后,许可量增加。当许可量为零时,线程阻塞。

19、什么是Leader/Followers模式

  • 有若干个线程(一般组成线程池)用来处理大量的事件
  • 有一个线程作为领导者,等待事件的发生;其他的线程作为追随者,仅仅是睡眠。
  • 假如有事件需要处理,领导者会从追随者中指定一个新的领导者,自己去处理事件。
  • 唤醒的追随者作为新的领导者等待事件的发生。
  • 处理事件的线程处理完毕以后,就会成为追随者的一员,直到被唤醒成为领导者。
  • 假如需要处理的事件太多,而线程数量不够(能够动态创建线程处理另当别论),则有的事件可能会得不到处理。

所有线程会有三种身份中的一种:leader和follower,以及一个干活中的状态:proccesser。它的基本原则就是,永远最多只有一个leader。而所有follower都在等待成为leader。线程池启动时会自动产生一个Leader负责等待网络IO事件,当有一个事件产生时,Leader线程首先通知一个Follower线程将其提拔为新的Leader,然后自己就去干活了,去处理这个网络事件,处理完毕后加入Follower线程等待队列,等待下次成为Leader。这种方法可以增强CPU高速缓存相似性,及消除动态内存分配和线程间的数据交换。

20、JDK5.0新增的concurrent包里面的BlockingQueue类用作阻塞队列,通常是一个业务流程里面,有些需要实时响应,而有些则没有要求那么高,所以可以通过这种阻塞队列实现的生产者/消费者模式来达到缓冲的效果,这个工具类主要是优化了之前实现多线程时使用wait()、notify()常常需要顾及到多线程并发时会出现的各种问题,比如造成死锁。
阻塞队列的成员有:

队列有界性锁数据结构
ArrayBlockingQueuebounded(有界)加锁arrayList
LinkedBlockingQueueoptionally-bounded加锁linkedList
PriorityBlockingQueueunbounded加锁heap
DelayQueueunbounded加锁heap
SynchronousQueuebounded加锁无
LinkedTransferQueueunbounded加锁heap
LinkedBlockingDequeunbounded无锁heap
  1. ArrayBlockingQueue:是一个用数组实现的有界阻塞队列,此队列按照先进先出(FIFO)的原则对元素进行排序。支持公平锁和非公平锁。【注:每一个线程在获取锁的时候可能都会排队等待,如果在等待时间上,先获取锁的线程的请求一定先被满足,那么这个锁就是公平的。反之,这个锁就是不公平的。公平的获取锁,也就是当前等待时间最长的线程先获取锁】
  2. LinkedBlockingQueue:一个由链表结构组成的有界队列,此队列的长度为Integer.MAX_VALUE。此队列按照先进先出的顺序进行排序。
  3. PriorityBlockingQueue:一个支持线程优先级排序的无界队列,默认自然序进行排序,也可以自定义实现compareTo()方法来指定元素排序规则,不能保证同优先级元素的顺序。
  4. DelayQueue:一个实现PriorityBlockingQueue实现延迟获取的无界队列,在创建元素时,可以指定多久才能从队列中获取当前元素。只有延时期满后才能从队列中获取元素。(DelayQueue可以运用在以下应用场景:1.缓存系统的设计:可以用DelayQueue保存缓存元素的有效期,使用一个线程循环查询DelayQueue,一旦能从DelayQueue中获取元素时,表示缓存有效期到了。2.定时任务调度。使用DelayQueue保存当天将会执行的任务和执行时间,一旦从DelayQueue中获取到任务就开始执行,从比如TimerQueue就是使用DelayQueue实现的。)
  5. SynchronousQueue:一个不存储元素的阻塞队列,每一个put操作必须等待take操作,否则不能添加元素。支持公平锁和非公平锁。SynchronousQueue的一个使用场景是在线程池里。Executors.newCachedThreadPool()就使用了SynchronousQueue,这个线程池根据需要(新任务到来时)创建新的线程,如果有空闲线程则会重复使用,线程空闲了60秒后会被回收。
  6. LinkedTransferQueue:一个由链表结构组成的无界阻塞队列,相当于其它队列,LinkedTransferQueue队列多了transfer和tryTransfer方法。
  7. LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。队列头部和尾部都可以添加和移除元素,多线程并发时,可以将锁的竞争最多降到一半。

21、偏向锁的获取过程(假设开启了偏向锁优化):
(1)初始时对象处于biasable状态,并且ThreadID为0即biasable & unbiased状态(这里不讨论epoch和age)
(2)当一个线程试图锁住一个处于biasable & unbiased状态的对象时,通过一个CAS将自己的ThreadID放置到Mark Word中相应的位置,如果CAS操作成功进入第(3)步否则进入(4)步
(3)当进入到这一步时代表当前没有锁竞争,Object继续保持biasable状态,但是这时ThreadID字段被设置成了偏向锁所有者的ID,然后进入到第(6)步
(4)当前线程执行CAS获取偏向锁失败(这一步是偏向锁的关键),表示在该锁对象上存在竞争并且这个时候另外一个线程获得偏向锁所有权。当到达全局安全点(safepoint)时获得偏向锁的线程被挂起,并从偏向锁所有者的私有Monitor Record列表中获取一个空闲的记录,并将Object设置为LightWeight Lock状态并且Mark Word中的LockRecord指向刚才持有偏向锁线程的Monitor record,最后被阻塞在安全点的线程被释放,进入到轻量级锁的执行路径中,同时被撤销偏向锁的线程继续往下执行同步代码。
(5)当一个线程试图锁住一个处于biasable & biased并且ThreadID不等于自己的ID时,这时由于存在锁竞争必须进入到第(4)步来撤销偏向锁。
(6)运行同步代码块

【K8S系列】Kubernetes 中 Pod 无法通过 Service 名称访问服务的 DNS 解析失败问题【已解决】 在 Kubernetes 中,Service 提供了一种稳定的方式,通过名称访问一组 Pod。当其他 Pod 无法通过 Service 名称访问服务,并且出现 DNS 解析失败时,通常会导致应用无法正常工作。本文将详细分析此问题的常见原因及其解决方案。 阅读详情

相关推荐

Vivado ILA调试全攻略:从HDL实例化到Block Design的5个实战技巧

本文全面解析了Vivado集成逻辑分析仪(ILA)的五种核心调试方法,涵盖从HDL代码实例化到Block Design集成的实战技巧。详细对比了不同方法的优缺点与适用场景,并重点介绍了如何利用Debug Hub高效管理多时钟域复杂调试,旨在帮助FPGA开发者精准定位问题,显著提升板级调试效率。

weixin_29214199的博客 376

java服务程序假死(进程存在但请求无响应)的几种原因

java服务程序假死(进程存在但请求无响应)的几种原因

liaomingwu的专栏 3万+

MFC+Modbus-Tcp协议实现温湿度传感器采集

本文简单介绍MFC使用-Tcp通信实现系列MODBUSTCP型温湿度传感器采集数据。

zhigang_zhao的博客 2832

Java线程通信--假死问题

死锁和阻塞的区别: 死锁:是由于两个对象在拥有一份资源的情况下申请另一份资源,而另一份资源恰好又是这两个对象所持有的,导致两个对象无法完成操作,且所持资源无法释放。 阻塞:是由于资源不足引起的排队等待的现象。 “假死”的现象就是全部线程都进入了WAITING状态(死锁),则程序就不再执行任何业务功能了,整个项目呈停止状态。 这里以常见的生产者消费者模型分析: import lombok.SneakyThrows; public class ProduceConsumerSync { //定义变量

softnothings的博客 1691

基于SOCKET的***网络软件的设计与实现

二、基于SOCKET的网络软件的需求。2、概要设计:画出软件系统结构图。3、详细设计:软件的详细设计,如类图、序列图、重要的算法流程图或伪代码,等等。4、实现:软件基本功能相关的截图和关键代码。

Recursions的博客 1371

支持向量机算法之鸢尾花特征分类【机器学习】

支持向量机(SVM)是一种二元分类模型。它的基本模型是在特征空间中定义最大区间的线性分类器,这使它不同于感知器;支持向量机还包括核技术,这使得它本质上是一个非线性分类器。支持向量机的学习策略是区间最大化,它可以形式化为求解凸二次规划的问题,等价于正则化铰链损失函数的最小化。支持向量机的学习算法是求解凸二次规划的优化算法。Scikit learn(sklearn)是机器学习中常见的第三方模块。它封装了常见的机器学习方法,包括回归、降维、分类、聚类等。实例的特征向量(以2D为例)映射到空间中的一些点,如下图中的

一键难忘的博客 4971

测试代码,解决java gui swing多线程界面假死、僵死问题,实现界面动态刷新,动态同步更新数据

(原创) 测试代码,解决java gui swing多线程界面假死、僵死问题,实现界面动态刷新,动态更新,同步显示数据 主类: package testguimulitiplethread; /** * * @author Administrator */ public class Main {     /**      * @param args the

极品小肥羊的博客 5656

华为OD机试2025A卷 - 用户调度问题(Java & Python& JS & C++ & C )

题目要求每个用户依次选择当前所能选择的最小资源消耗策略,并且若有多个策略的资源消耗相同,则选择最后一个策略。每个用户的选择是独立的,只考虑该用户的策略和相邻用户的约束,不考虑整个调度序列的全局资源消耗。每个用户根据自己的当前状态(即自己的三种选择的资源消耗)做出局部最优选择:在当前可选的策略中,选择消耗最小的那个。如果有多个最小值,则选择最后一个(根据题意)。这一选择是局部的最优,即在当下最有利的选择,但并不保证最终的整体系统资源消耗是最小的。

算法大师! 1万+

Java 系统假死,重启之后就好了,是什么原因

2. 死锁:Java多线程程序中,如果线程之间相互等待对方释放资源,就会发生死锁。您可以通过仔细设计和管理线程之间的同步和互斥关系,以避免死锁的发生。4. 第三方库或框架问题:有时候,Java应用程序会使用第三方库或框架,这些库或框架存在漏洞或不稳定性,导致系统假死。1. 内存泄漏:Java应用程序在运行过程中会发生内存泄漏,导致系统资源耗尽,从而导致系统假死。您可以通过检查代码,确保及时释放不再使用的对象,以避免内存泄漏的问题。您可以通过优化代码,减少资源占用,以避免资源耗尽的问题。

WXY888888888的博客 1316

Python 爬虫实战:arXiv 学术论文 PDF 批量下载(含反爬策略与文件命名规范)

arXiv 是全球最大的免费开放预印本论文平台之一,涵盖物理学、数学、计算机科学等多个学科领域。研究人员、学生和工程师常常需要批量下载论文 PDF 进行文献综述、构建机器学习数据集或进行文本挖掘研究。然而,手动逐篇下载论文效率低下,因此开发一个自动化批量下载工具显得尤为重要。

yansideyucsdn的博客 1817

基于STM32的智能鱼缸设计

为了缓解学习、生活、工作带来的压力,提升生活品质,许多人喜欢在家中、办公室等场所养鱼。为节省鱼友时间、劳力、增加养鱼乐趣;为此,本文基于STM32单片机设计了一款智能鱼缸。该鱼缸可以实现水温检测、水质检测、自动或手动换水、氛围灯灯光变换和自动或手动喂食等功能为一体的控制系统,可通过控制键进行一键控制。...

1万+

Java多线程详解(一)Java多线程入门

最近听很多面试的小伙伴说,网上往往是一篇一篇的Java多线程的文章,除了书籍没有什么学习多线程的一系列文章。但是仅仅凭借一两篇文章很难对多线程有系统的学习,而且面试的时候多线程这方面的知识往往也是考察的重点,所以考虑之下决定写一系列关于Java多线程的文章。文章参考了高老师的《Java多线程编程核心技术》。力争使用最短的篇幅把Java多线程的知识作以系统的讲述。 本节思维导图: 思维导图...

刘成 2475

智能车图像处理0-图像处理整体框架思路

1.总体框架如上所示,具体代码请查看后续文章。2.因为参与竞赛时间是大二,所以在编程中有许多不规范的地方(如变量的命名),大家见谅。3.原创文章,请勿侵权=-=

taiyuezyh的博客 1万+

【Java多线程】Java多线程技能

到 1. 进程和多线程的概念及线程的优点 提到多线程这个技术就不得不提及“进程”这个概念,在“百度百科”中对进程的解释如下: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。 进程是受操作系统管理的基本运行单元。 那什么是线程呢? 线程可以理解成是在

一定要站在自己热爱的生活里闪闪发光 4万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Java 多线程详解

多线程(Multithreading)是指在一个程序中同时执行多个线程的能力。线程是进程中的一个执行路径,多线程允许程序在同一时间内执行多个操作。Java 中的多线程可以通过并发处理来提高程序的性能和响应速度,尤其在处理复杂计算、大量 I/O 操作或并发任务时非常有用。多线程使得程序可以同时执行多个任务,充分利用CPU资源,提升程序性能,增强响应性,并简化程序的复杂度。尽管多线程编程带来了一些挑战,如线程安全和死锁问题,但合理设计和使用多线程可以显著改善程序的整体表现。

goTsHgo的博客 2040

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Java技术——Java多线程学习

0.前言 转载请标明出处:http://blog.youkuaiyun.com/seu_calvin/article/details/52400927 学习多线程之前需要先了解以下几个概念。 进程:一般指一个程序运行时的实例,每个进程有自己独立的地址空间。一个进程无法直接访问另一个进程的数据。 线程:是CPU调度的最小单元,一个进程可以有很多线程,每条线程可以并行执行不同的任务。并且每个线程有独立的运...

关于Android开发的一些技术点总结 ╮( ̄▽ ̄”)╭ 1万+

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Java多线程详解

线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。

坏蛋阿土的博客 6819

java多线程

在计算机中,我们把一个任务称为一个进程,浏览器就是一个进程,视频播放器是另一个进程,类似的,音乐播放器和Word都是进程。某些进程内部还需要同时执行多个子任务。例如,我们在使用Word时,Word可以让我们一边打字,一边进行拼写检查,同时还可以在后台进行打印,我们把子任务称为线程。进程和线程的关系就是:一个进程可以包含一个或多个线程,但至少会有一个线程。操作系统调度的最小任务单位其实不是进程,而是线程。

m0_60301012的博客 775

java多线程是什么_Java多线程是什么

本篇文章将介绍一下多线程和其实例。Java编写程序都运行在在Java虚拟机(JVM)中,在JVM的内部,程序的多任务是通过线程来实现的。每用java命令启动一个java应用程 序,就会启动一个JVM进程。在同一个JVM进程中,有且只有一个进程,就是它自己。在这个JVM环境中,所有程序代码的运行都是以线 程来运行。一般常见的Java应用程序都是单线程的。比如,用java命令运行一个最简单的Hello...

weixin_33050129的博客 378

java多线程应用_Java多线程的应用总结

多线程的好处:在java中通常每一个任务称为一个线程,但是多线程实现一个程序同时执行多个任务。直接了当的说多线程可以把任务分块执行,分块后可以同时进行而不用等待。 如下载文件,浏览网站时加载图片,通过多线程就可以实现多文件下载,一下做好几个工作,这样效率更高,线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实...

weixin_31081671的博客 774

JAVA多线程是什么

一、 什么是多线程: 我们现在所使用操作系统都是多任务操作系统(早期使用的DOS操作系统为单任务操作系统),多任务操作指在同一时刻可以同时做多件事(可以同时执行多个程序)。 多进程:每个程序都是一个进程,在操作系统中可以同时执行多个程序,多进程的目的是为了有效的使用CPU资源,每开一个进程系统要为该进程分配相关的系统资源(内存资源) 多线程:线程是进程内部比进程更小的执行单元(执行流|程序片段),每个线程完成一个任务,每个进程内部包含了多个线程每个线程做自己的事情,在进程中的所有线程共享该进程的资源; 主

qq_45022104的博客 4446

Java实现多线程

文章对Java多线程各个方面进行讲解,以几种经典的线程问题来讲述线程的通信和同步问题,以及线程的几种创建方法。

qq_56627079的博客 2489
上一篇: 数据库调优随笔
下一篇: InnoDB存储引擎 第2章笔记
Mario_Hu
博客等级 码龄10年 4粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值