我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么在java中实现多线程的互斥与同步

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么在java中实现多线程的互斥与同步

这篇文章将为大家详细讲解有关怎么在java中实现多线程的互斥与同步,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

一、线程互斥与同步

互斥:指的是多个线程不能同时访问共享变量
同步:指的是多个线程按指定的顺序执行操作

在同时有多个线程运行过程中,如何达到互斥和同步呢?

  • 加锁即可

在此使用黑马笔记中room例子来说明锁。(ps: 以前就了解锁,但总会记乱,发现使用形象化记忆后就很清楚)

怎么在java中实现多线程的互斥与同步

解决互斥

  • 锁就相当于上图的房子,里面放着会被并发访问的共享变量

  • 此时绿色区域(owner)无线程,此时多个线程想并发访问房子里的共享变量,那么只允许其中一个线程进入房子访问,并把房门锁上。

  • 剩下的没有拿到锁的线程只能在entrylist中排队

  • owner中的线程访问结束后会离开房子,并告诉entrylist的线程可以进房子了

  • entrylist的线程开始新一轮的挣锁,如此反复

  • 这样就能解决互斥的问题

解决同步

(这涉及到为什么wait(),notify()方法需要用锁,就是因为只有用了锁才能完成同步,那么怎么完成的呢?)

  • 多个线程同时启动,如果希望B线程在A线程之后执行

  • 那么当B先抢到锁,即先进入了房子,此时A只能在entrylist中排队

  • 为了让A先执行,那么可以先让B进入蓝色区域,即waitset中等待,并且把门打开,告诉entrylist中的线程可以进来了

  • 那么A进来后,执行完任务,临走时通知waitset中的B,B再回到绿色区域执行任务就能保证有序了

  • 这样就能解决同步问题

那么room这个数据结构其实就是synchronized的核心了,接下来总结synchronized原理的时候会一直用room的例子

二、synchronized

很多人对synchronized原理的理解也就停留在知道字节码有个monitor关键字来管理锁,再浅一点的只知道怎么用,再者懂得深一点的却记不住。我之前就是想深入了解一下但觉得苦涩,就看不下去了,看了黑马的笔记我觉得这玩意儿其实很简单,所以好的老师还是比较重要的。那么在此我也记录一下怎么更好的去理解synchronized的底层原理

从字节码我们可以知道synchronized的底层就是关联了一个monitor,那么这玩意儿是个什么东西,怎么实现锁的功能呢?

首先,可以把monitor的数据结构简化成上图的room,具体点描述如下图

怎么在java中实现多线程的互斥与同步

  • synchronized(锁对象)的时候,相当于让锁对象绑定了一个monitor(具体绑定方法不打算在后面总结)

  • 那么多个线程中方法涉及到该锁对象时,都会来访问锁对象对应的monitor

  • 此时线程thread-2抢到了锁,操作就是让monitor中的owner字段指向thread-2线程,意味着当前线程获取到了基于该monitor的锁

  • 其他没抢到锁的,monitor会将他们放在Entrylist中等待,这些线程只能在队列中等着

  • thread-2线程完成操作后就会退出,并通知entrylist的线程重新抢锁

  • 如果在执行过程中,线程调用了wait()方法,monitor就会将他们放入waitset中等待别人唤醒

  • (看回room结构)owner进入waitset后会把门打开,让entrylist的线程进来

  • 直到某时刻owner中有线程调用notify()方法,waitset中的线程才会被唤醒,唤醒后会进入entrylist中重新抢锁

以上就是synchronized的原理。有人就会问了,你说的这些文字我都懂啊,搞个图摆在这也没啥用。

接下来我将从上图直接回答下面的常见的问题

wait()和notify()为什么都得在synchronized后使用?

  • wait()就是将线程放入waitset中,那么waitset是在room里面的,不上锁怎么能进room中?同理,不进入room,在门外怎么使用notify()怎么能叫醒waitset中的线程?

wait()会释放锁吗?

  • 废话,不开门的话,怎么放线程进来,就更别提唤醒了

notifyALL()为什么不会唤醒其他锁对象的线程?

  • 进哪个room才能叫哪个waitset,进了Aroom当然只能叫醒A的waiset了

说说synchronized的原理?

  •  把图画出来就行了

线程什么时候从runnable变成waiting,什么时候变成block?

  • 看图,进入waiset就是wait,所以调wait()就变成waiting状态进入entrylist就是block,所以被唤醒后以及没抢到锁都变block 。。。。。。。。。。。。

注意了,这里涉及monitor的原理都是synchronized最根本的原理,也称重量级锁,可以看到monitor会频繁切换线程状态,效率比较低。后来synchronized改进了,在使用monitor前还有好几种方案,分别为偏向锁,轻量锁,以及自旋优化。这部分也是面试常考点,也容易记乱,但用图例去记就很清楚。

那么接下来就说说synchronized的改进

三、轻量锁与偏向锁

轻量锁与偏向锁的核心都是先不让线程冲突的时候直接去找monitor,而是先用锁对象的对象头字段来解决冲突

(写博客好累啊。。。算了我就总结一些自己觉得关键的地方吧)

轻量锁

  • 对于轻量锁而言,每个线程维护了一个锁记录,抢占锁的过程就是用CAS将自己的信息与锁对象的对象头mark word部分交换

  • 这样其他慢一步的线程CAS会失败,就意识到锁已经被占了

  • 可重入只需要在占锁的时候判断锁对象的markword记录的是不是自己的线程id即可,是的话就能够获取锁,也就是叠加一个锁记录

  • 释放锁就意味着删除锁记录,直到锁记录清空,就将锁对象头部被修改的字段变回原样

  • 轻量锁是认为不会有竞争,如果发生了线程竞争,锁需要升级,不然上述方法没有像monitor的entrylist来管理其他竞争暂时没拿到锁的线程

  • 锁升级就是锁膨胀,直接调monitor来管理,就将owner指向当前线程,然后竞争线程去entrylist排队

  • 其中涉及自旋优化,就是线程竞争时,第二个线程不用立刻去entrylist中,这样又要涉及上下文切换,可以自旋一会看锁能否抢到

偏向锁

  • 轻量锁每次占锁都要用一次CAS来更新锁对象头,如果本来就没啥竞争那CAS就是无用的操作了

  • 为了解决这个问题,线程抢锁成功后直接把自己的ID刻在锁对象头中,需要判断重入时只需判断ID是否相同即可

Java有哪些集合类

Java中的集合主要分为四类:1、List列表:有序的,可重复的;2、Queue队列:有序,可重复的;3、Set集合:不可重复;4、Map映射:无序,键唯一,值不唯一。

关于怎么在java中实现多线程的互斥与同步就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么在java中实现多线程的互斥与同步

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

怎么在java中实现多线程的互斥与同步

这篇文章将为大家详细讲解有关怎么在java中实现多线程的互斥与同步,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。一、线程互斥与同步互斥:指的是多个线程不能同时访问共享变量同步:指的是多个线程
2023-06-15

C++多线程中的线程同步与互斥量实例分析

本篇内容介绍了“C++多线程中的线程同步与互斥量实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!线程同步/* 使用多线程实现买票
2023-06-30

Python实现的多线程同步与互斥锁功能示例

本文实例讲述了Python实现的多线程同步与互斥锁功能。分享给大家供大家参考,具体如下:#! /usr/bin/env python #coding=utf-8 import threading import time ''' #1、不加锁
2022-06-04

Java线程同步与互斥:多线程编程的基石,不可不知

Java线程同步与互斥是多线程编程中的重要概念,使用正确的方法可以避免因共享资源而导致的多线程冲突。本文介绍了Java线程同步与互斥的基础知识,通过示例演示了如何使用同步机制和互斥锁来保证多线程程序的正确性。
Java线程同步与互斥:多线程编程的基石,不可不知
2024-02-09

Java线程同步与互斥:从原理到实践,打造稳定的多线程程序

Java中的线程同步与互斥机制对于构建稳定可靠的多线程程序至关重要,本文将从原理到实践深入解析线程同步与互斥,掌握相关概念和实现方法,助力打造稳定高效的多线程应用。
Java线程同步与互斥:从原理到实践,打造稳定的多线程程序
2024-02-09

Java线程同步与互斥:揭秘并发编程的秘密

Java线程同步与互斥揭秘并发编程的秘密 Java、线程、同步、互斥、并发编程 Java线程同步和互斥机制提供了对共享资源的访问控制,确保了并发程序的正确性和一致性。本文将详细探讨这两种机制,并通过演示代码讲解其工作原理和应用场景。
Java线程同步与互斥:揭秘并发编程的秘密
2024-02-09

Java中怎么实现多线程同步

今天就跟大家聊聊有关Java中怎么实现多线程同步,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。让我们从JVM的角度来看看锁这个概念:在Java程序运行时环境中,JVM需要对两类线程共
2023-06-17

Java线程同步与互斥:让你的程序在并发世界里舞动

在并发编程中,线程同步与互斥是保障数据一致性和程序正确性的关键。本文将深入探讨Java线程同步与互斥机制,并提供代码示例,帮助您理解和掌握这些重要概念,让您的程序在并发世界里舞动。
Java线程同步与互斥:让你的程序在并发世界里舞动
2024-02-09

Java中怎样实现多线程同步

本篇文章给大家分享的是有关Java中怎样实现多线程同步,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。不同步时的代码Bank.java package threadTest;
2023-06-17

Java线程同步与互斥:揭开多线程编程的面纱,拥抱并发世界的挑战

多线程编程是并发编程的一种重要手段,它允许程序在多个线程中同时执行代码,从而提高程序的性能和效率。然而,多线程编程也引入了一些新的挑战,其中之一就是线程同步与互斥的问题。
Java线程同步与互斥:揭开多线程编程的面纱,拥抱并发世界的挑战
2024-02-09

Java线程同步与互斥:理论与实战并存,打造高并发系统

多线程编程是现代系统开发中不可或缺的部分,Java线程同步和互斥机制是开发人员必须掌握的核心知识。本文将从理论到实践全面剖析Java线程同步和互斥,并提供多个代码示例帮助读者理解和掌握。
Java线程同步与互斥:理论与实战并存,打造高并发系统
2024-02-09

Java线程同步与互斥:从零开始,打造高效的并发程序

: 在Java并发编程中,线程同步和互斥是两个至关重要的概念。通过巧妙地运用同步和互斥技术,可以确保并发执行的程序不会出现数据竞争或其他不一致的情况。本文将从零开始,介绍Java线程同步和互斥的基础知识,并通过代码示例来演示如何使用这些技术来编写高效的并发程序。
Java线程同步与互斥:从零开始,打造高效的并发程序
2024-02-09

C#多线程中的互斥锁Mutex怎么用

本篇内容主要讲解“C#多线程中的互斥锁Mutex怎么用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#多线程中的互斥锁Mutex怎么用”吧!一、简介Mutex的突出特点是可以跨应用程序域边界对
2023-06-30

Java中怎么利用Synchronized实现多线程同步

这期内容当中小编将会给大家带来有关Java中怎么利用Synchronized实现多线程同步,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。使用同步的原因1. 在系统中对访类要使用多线程进行访问;2. 在该类
2023-06-17

在java项目中如何实现同步多线程

本篇文章给大家分享的是有关在java项目中如何实现同步多线程,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。 java多线程的同步方法实例代码先看一个段有关银行存钱的代码:cla
2023-05-31

在Java中,如何实现多线程之间的同步与通信?(Java多线程编程时,应如何确保线程间的同步与有效通信?)

本文详细介绍了Java多线程编程中的同步和通信机制。为了实现同步,可以使用synchronized关键字、Lock接口或Semaphore。同步确保多个线程在访问共享资源时保持一致性。对于通信,共享内存、消息队列和管道等机制允许线程共享数据和协调任务。文中还提供了代码示例、最佳实践和问题的预防策略。通过这些机制,开发者可以创建同步且有效的Java多线程应用程序。
在Java中,如何实现多线程之间的同步与通信?(Java多线程编程时,应如何确保线程间的同步与有效通信?)
2024-04-02

Java线程同步与互斥:多线程编程的必备技能,掌握它,让你的程序如丝般顺滑

多线程编程是一项复杂的技能,需要对线程同步和互斥有深入的理解。本文将介绍Java中的线程同步和互斥,并提供示例代码,帮助您掌握多线程编程的必备技能,让您的程序运行顺畅如丝。
Java线程同步与互斥:多线程编程的必备技能,掌握它,让你的程序如丝般顺滑
2024-02-09

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录