线程的同步

news2025/1/16 1:14:23

一、互斥锁

  1. java语言中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。
  2. 每个对象都对应与一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有 一个线程访问该对象。
  3. 关键字synchronized用来与对象的互斥锁联系。当某个对象用synchronized修饰时,表明该对象在任一时刻只能由一个线程访问。
  4. 同步的局限性:导致程序的执行效率降低。
  5. 同步方法(非静态)的锁可以是this,也可以是其他对象(保证是同一个对象)。
  6. 同步方法(静态)的锁为当前类本身,即Dog.class

1.1 同步机制

同步机制是指在对某些共享数据进行访问时,不允许多个线程同时访问导致数据错误,而要求同一时刻只能有一个线程访问共享数据的方法。一般我们通过给访问共享数据区的部分代码上锁的方式来实现同步。上锁之前需要先寻找访问共享数据的那一部分代码,尽量让上锁的代码尽可能的少,提高代码的执行效率。

1.2 生命周期

在线程的生命周期中,官方文档中记录了六个状态。分别是:

状态名说明
NEW尚未启动的线程
RUNNABLE正在java虚拟机中执行的线程
BLOCK受到阻塞并等待某个监视器锁的线程
WAITING无限期等待另一个线程来执行某一特定操作的线程
TIMED WAITING等待另一个指定时间内操作的线程
TERMINATED线程已经结束执行。

其中Runnable状态有很多人又将其分成了正在被CPU执行和等待CPU调度两个状态。当线程由于在等待锁的释放而无法执行时,该线程就处于BLOCK状态。使用下面这段代码可以查看线程的各个状态:

public class ThreadState_ {
    public static void main(String[] args) throws InterruptedException {
        T t = new T();
        System.out.println(t.getName() +" 状态 "+ t.getState());
        t.start();

        while(Thread.State.TERMINATED != t.getState()){
            System.out.println(t.getName() +" 状态 "+ t.getState());
            Thread.sleep(500);
        }
        System.out.println(t.getName() +" 状态 "+ t.getState());
    }
}

class T extends Thread{
    
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("hi " + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

1.3 synchronized 关键字

互斥锁是通过synchronized来修饰方法和代码块来实现,通过使用该关键字修饰方法时有默认的锁对象。当修饰静态方法时,默认的锁对象为当前类.class。当修饰非静态方法时,默认的锁对象是this。使用该关键字修饰代码块时,格式为:

synchronized(锁对象){

}

在选择修饰方法还是修饰代码块时,建议选择修饰代码块,以便提供代码的执行效率。但是使用修饰代码块来上锁时,需要手动选择锁对象。选择锁对象的原则就是要保证多个线程在执行过程中的锁对象必须是同一个对象实例

常用的锁对象分别有:this对象、Object对象、当前类.class。同一个类的不同实例调用的当前类.Class对象是唯一的。而前面两种对象相信大家都比较熟悉,在通过继承Thread类实现多线程时,由于在main方法中会创建多个子线程的实例,因此无法使用synchronized(this)来实现线程的同步。这里通过代码来演示一下该情况无法锁住的情形,其中使用this对象和Object对象都无法锁住,出现了票数超买的情况。

public class SellTicket {
    public static void main(String[] args) {
        SellTicket01 sellTicket01 = new SellTicket01();
        SellTicket01 sellTicket02 = new SellTicket01();
        SellTicket01 sellTicket03 = new SellTicket01();

        //使用synchronize(this), 仍然会出现票数超买现象
        sellTicket01.start();
        sellTicket02.start();
        sellTicket03.start();
    }
}

//使用Thread方式
class SellTicket01 extends Thread{
    private static int ticketNum = 100;
    Boolean loop = true;//线程标志

    public void sell(){
        synchronized (this){//上锁
            if(ticketNum <= 0){
                System.out.println("售票结束...");
                loop = false;
                return;
            }

            //休眠50ms
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("窗口 " + Thread.currentThread().getName()
                    + " 售出1张票" + "剩余票数 = " + (--ticketNum));
        }
    }
    
    public void run() {
        while (loop){
           sell();
        }
    }
}

超买
而使用当前类.Class则没有出现该情况。当然如果你使用实现Runnable接口的方式来实现多线程,由于只创建了一个线程实例,前面两个锁对象也可以实现同步的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/794283.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML不常用但是好用的标签

sub sup <p>这个文本包含 <sub>111</sub>文本。</p> <p>这个文本包含 <sup>上标</sup> 文本。</p>下标文本将会显示在当前文本流中字符高度的一半为基准线的下方&#xff0c;但是与当前文本流中文字的字体和字号都是一样的。…

Xilinx AXI VIP使用教程

AXI接口虽然经常使用&#xff0c;很多同学可能并不清楚Vivado里面也集成了AXI的Verification IP&#xff0c;可以当做AXI的master、pass through和slave&#xff0c;本次内容我们看下AXI VIP当作master时如何使用。 新建Vivado工程&#xff0c;并新建block design&#xff0c;命…

YOLOv7改进:CVPR 2023 | SCConv: 即插即用的空间和通道重建卷积

1.该文章属于YOLOV5/YOLOV7/YOLOV8改进专栏,包含大量的改进方式,主要以2023年的最新文章和2022年的文章提出改进方式。 2.提供更加详细的改进方法,如将注意力机制添加到网络的不同位置,便于做实验,也可以当做论文的创新点。 2.涨点效果:添加 SCConv,经过测试,有效涨点。…

【FAQ】关于无法判断和区分用户与地图交互手势类型的解决办法

一&#xff0e; 问题描述 当用户通过缩放手势、平移手势、倾斜手势和旋转手势与地图交互&#xff0c;控制地图移动改变其可见区域时&#xff0c;华为地图SDK没有提供直接获取用户手势类型的API。 二&#xff0e; 解决方案 华为地图SDK的地图相机有提供CameraPosition类&…

labview 信号量实现互斥 避免竞争写

上一篇文章中描述了事件发生、集合点、通知器、信号量。 本文进一步举例描述信号量实现互斥&#xff0c;避免竞争写。 1.不用信号量的例子 图1-不用信号量的结果都不同&#xff0c;不为0 图2-不用信号量的例子&#xff0c;程序框图 2.用信号量的例子 图3-用信号量的例子&…

手工测试如何转向自动化测试

手工测试的迷茫&#xff1a;除了重复劳动&#xff0c;到底还有什么&#xff1f; 我是在2008年毕业的&#xff0c;三本的学校&#xff0c;不上不下的专业水平&#xff0c;毕业的时候&#xff0c;恰好遇到了金融危机。校园招聘里阴差阳错的巧合&#xff0c;让我走上了软件测试工…

运算放大器基础(一)

5.1.1反馈的基本概念 在电子电路中,将 输出量 (输出电压或输出电流)的一部分或全部通过一定的电路形式作用到 输入回路&#xff0c;用来影响其输入量(放大电路的输入电压或输入电流)的措施称为 反馈。具体框图如下&#xff1a;反馈类型判断 正反馈与负反馈 正反馈&…

CHI协议之DVM操作

本文部分内容参考了CHI的Cache Stashing和DVM操作_谷公子的藏经阁的博客-CSDN博客 □ 注意此处RNF发送的noncopyback data, 只有8byte; □ MN会发送两个SNP给每个RNF, 因为一个SNP&#xff0c;携带的信息不够&#xff1b; □ 如果MN具备将来自同一个源头的non-sync/sync dvmop操…

详解Mybatis之自动映射 自定义映射问题

编译软件&#xff1a;IntelliJ IDEA 2019.2.4 x64 操作系统&#xff1a;win10 x64 位 家庭版 Maven版本&#xff1a;apache-maven-3.6.3 Mybatis版本&#xff1a;3.5.6 文章目录 一、Mybatis中的自动映射是什么&#xff1f;二、Mybatis中的自定义映射是什么&#xff1f;三、为什…

华东师范大学计算机考研分析

关注我们的微信公众号 姚哥计算机考研 更多详情欢迎咨询 华东师范大学&#xff08;B&#xff09;考研难度&#xff08;☆☆☆☆&#xff09; 华东师范大学计算机考研招生学院是计算机科学与技术学院、软件工程学院网址和数据科学与工程学院。目前均已出拟录取名单。 华东师…

前端JS 展示上传图片缩略图(本地图片读取)

需求&#xff1a; 点击上传图片按钮&#xff0c;选择图片以后&#xff0c;不请求后端接口&#xff0c;直接将图片展示在缩略图中。 解决方案&#xff1a; 使用 FileReader 和 FileReader 中的 readAsDataURL 方法。 第一步 从input[type“file”] (上传文件标签) 里面拿到fil…

解密直播美颜SDK和滤镜算法的工作原理:如何实现实时美化效果

直播美颜已成为许多直播平台的核心功能之一。通过美颜技术&#xff0c;主播可以在直播过程中实时改善自己的外貌&#xff0c;给观众带来更好的视觉体验。而实现这一效果的关键在于直播美颜SDK和滤镜算法。 一、美颜SDK的工作原理 美颜SDK是一种集成了美颜算法的软件开发工具包…

亚马逊奥地利卖家出口额创新高!2022年突破5.5亿欧元!

近日亚马逊报告说&#xff0c;2022年奥地利中小企业的出口额达到5.5亿欧元以上&#xff0c;比上一年增长了10%&#xff0c;延续了跨境销售的趋势。去年&#xff0c;奥地利卖家在亚马逊上销售了约2000万件产品。 亚马逊宣称&#xff0c;通过其全球22个站点&#xff0c;奥地利的…

[ 容器 ] consul 容器服务更新与发现

目录 什么是服务注册与发现什么是consulconsul 部署consul 服务器 registrator服务器consul-templateconsul 多节点 什么是服务注册与发现 服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的&#xff0c;不保障高可用性&#xff0c;也不考虑服务的压力承…

学习 C语言第二天 :C语言数据类型和变量(下)

目录&#xff1a; 1.变量的介绍以及存储 2.算术操作符、赋值操作符、单目操作符 3.scanf和printf的介绍 1.变量的介绍以及存储 1.1.变量的创建 了解了什么是类型了&#xff0c;类型是用来创建变量的。 变量是什么呢&#xff1f;在C语言当中不经常变的量称为常量&#xff0c;经常…

Python实战项目——O2O_优惠券使用情况分析(五)

O2O优惠券线下使用情况数据分析 一 项目简介 随着移动设备的完善和普及&#xff0c;移动互联网各行各业进入了高速发展阶段&#xff0c;这其中以O2O&#xff08;Online to Offline&#xff09;消费最为吸引眼球。据不完全统计&#xff0c;O2O行业估值上亿的创业公司至少有10家…

【Docker】Docker的服务更新与发现

consul 一、服务注册与发现1. 服务注册与发现的概念2. 服务发现的机制 二、consul 的概念1. 什么是 consul2. consul 的特性 三、consul 的部署1. consul 服务器架构2. consul 的部署过程2.1 环境配置2.2 consul 服务器建立 Consul 服务查看集群信息通过 http api 获取集群信息…

Jenkins 安装构建

一、CentOS 安装 1. 使用该存储库 sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key 2. 安装 Java yum install fontconfig java-11-openjdk配…

聚焦APP开发:理解并预防常见的安全问题

移动应用程序是我们日常生活中不可或缺的一部分&#xff0c;它帮助我们处理信息&#xff0c;完成任务&#xff0c;甚至更多。因此&#xff0c;移动应用程序在我们日常生活中的重要性是毋庸置疑的。随着越来越多的人使用智能手机和平板电脑进行工作和娱乐&#xff0c;移动应用程…

项目管理系统软件有哪些?别错过!这款超好用!(免费试用)

如今&#xff0c;很多企业都面临着复杂的业务流程和庞大的项目数量&#xff0c;为了更好地管理和协调这些项目&#xff0c;企业需要一个高效的项目管理系统。然而&#xff0c;传统的项目管理系统已经无法满足企业的需求了。 企业需要一种新型的项目管理系统来应对这些挑战。一…