同步方法及同步代码块

2023-11-06

synchronized方法和synchronized块

synchronized方法必须获得对象的锁才能执行,否则线程阻塞,方法一旦执行,就独占此锁,直到方法返回才释放锁,后面被阻塞的线程才能获得这个锁,继续执行

synchronized会影响效率

同步块synchronized(Obj){},Obj是同步监听器,第一个线程访问,所定Obj,完后解锁Obj,第二个才能访问

同步方法弊端:方法里面需要修改的内容才需要锁,锁的太多,浪费资源

package com.wuming.syn.synch;
//不安全的买票
public class UnSafeBuyTicket {
    public static void main(String[] args) {
        BuyTicket station = new BuyTicket();
        new Thread(station,"苦逼的我").start();
        new Thread(station,"牛逼的你们").start();
        new Thread(station,"可恶的黄牛党").start();
    }
}

class BuyTicket implements Runnable{
    //票
    private int ticketNums=10;
    boolean flag=true;//停止方式
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see Thread#run()
     */
    @Override
    public void run() {
        //买票
        while(flag){
            try {
                buy();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //synchronized同步方法,锁的是this BuyTicket
    private synchronized void buy() throws InterruptedException {
        //判断是否有票
        if (ticketNums<=0){
            flag=false;
            return;
        }
        //模拟延时
        Thread.sleep(100);
        //买票
        System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);
        //加了synchronized,安全
    /*    苦逼的我拿到10
                可恶的黄牛党拿到9
        可恶的黄牛党拿到8
                牛逼的你们拿到7
        可恶的黄牛党拿到6
                苦逼的我拿到5
        苦逼的我拿到4
                可恶的黄牛党拿到3
        牛逼的你们拿到2
                可恶的黄牛党拿到1*/
    }
}

===============

package com.wuming.syn;
//不安全的取钱
//两个人去银行取钱,账户
public class UnSafeBank {
    public static void main(String[] args) {
        //账户
        Account account = new Account(100,"结婚基金");
        Drawing you = new Drawing(account,50,"你");
        Drawing girlFriend = new Drawing(account,100,"girlFriend");
        you.start();
        girlFriend.start();
    }

}
//账户
class Account{
    int money;//余额
    String name;//卡名

    public Account(int money, String name) {
        this.money = money;
        this.name = name;
    }
}

//银行,模拟取款
class Drawing extends Thread{
    Account account;//账户
    //取了多少钱
    int drawingMoney;
    //现在手里有多少钱
    int nowMoney;

    public Drawing(Account account, int drawingMoney, String name) {
        super(name);//线程name
        this.account = account;
        this.drawingMoney = drawingMoney;
        this.nowMoney = nowMoney;
    }
//取钱
    //synchronized默认锁的是本身
    @Override
    public void run() {
        //锁的对象是变化的量,增删改;改成this就是指银行,线程不安全如下
   /*     结婚基金余额为:-50
        结婚基金余额为:-50
        你手里的钱50
                girlFriend手里的钱100*/
        synchronized (account){
            //判断有没有钱
            if(account.money-drawingMoney<0){
                System.out.println(Thread.currentThread().getName()+"钱不够,取不了");
                return;
            }
            //sleep可以放大问题的发生性
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //卡内余额=余额-你取的钱
            account.money=account.money-drawingMoney;
            //你手里的钱
            nowMoney=nowMoney+drawingMoney;
            System.out.println(account.name+"余额为:"+account.money);
            //Thread.currentThread().getName()=this.getName();
            System.out.println(this.getName()+"手里的钱"+nowMoney);
        }
        //使用同步块 synchronized (account),线程安全
    /*    结婚基金余额为:50
        你手里的钱50
        girlFriend钱不够,取不了*/


    }
}

===============

package com.wuming.syn.synch;

import java.util.ArrayList;
import java.util.List;

//线程不安全的集合
public class UnsafeList {
    public static void main(String[] args) {
        List<String> list=new ArrayList<String>();
        for (int i = 0; i < 10000; i++) {
            new Thread(()->{
                synchronized (list){//线程安全
                    list.add(Thread.currentThread().getName());
                }
            }).start();
        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(list.size());//每次运行都不够10000,线程不安全,两个线程同时操作同一个位置,
        //两个数组添加到同一个位置,就会覆盖掉,元素就会少

    }
}

10000

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

同步方法及同步代码块 的相关文章

  • 唯一索引或主键违规:“PRIMARY KEY ON PUBLIC.xxx”; SQL语句

    每当我的应用程序启动时 我都会收到以下错误消息 Caused by org h2 jdbc JdbcSQLException Unique index or primary key violation PRIMARY KEY ON PUBL
  • 菜单未显示在应用程序中

    由于某种原因 我的操作菜单在我的 Android Studio 应用程序中消失了 我正在按照教程学习如何创建 Android 应用程序 但最终遇到了这个问题 我正在使用 atm 的教程 http www raywenderlich com
  • 在 JTable 中移动行

    我使用 MVC 模式 并且有一个如下所示的 JTable List
  • 如何将 Java 赋值表达式转换为 Kotlin

    java中的一些东西就像 int a 1 b 2 c 1 if a b c System out print true 现在它应该转换为 kotlin 就像 var a Int 1 var b Int 2 var c Int 1 if a
  • 我需要在 Spring 中检查每个控制器中的有效会话吗? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 假设在 Spring Mvc 的 Web 应用程序中 我们是否需要检查每个控制器或 jsps 中的有效会话 我该如何解决 MVC 中的
  • Android Studio 在编译时未检测到支持库

    由于 Android Studio 将成为 Android 开发的默认 IDE 因此我决定将现有项目迁移到 Android studio 中 项目结构似乎不同 我的项目中的文件夹层次结构如下 Complete Project gt idea
  • JNI 不满意链接错误

    我想创建一个简单的 JNI 层 我使用Visual studio 2008创建了一个dll Win 32控制台应用程序项目类型 带有DLL作为选项 当我调用本机方法时 出现此异常 Exception occurred during even
  • 在浏览器中点击应用程序时播放框架挂起

    我正在 Play 中运行一个应用程序activator run 也许 5 次中有 3 次 它会挂起 当我去http localhost 9000 它就永远坐在那里旋转 我看到很多promise timed out错误也 我应该去哪里寻找这个
  • 在数据流模板中调用 waitUntilFinish() 后可以运行代码吗?

    我有一个批处理 Apache Beam 作业 它从 GCS 获取文件作为输入 我的目标是根据执行后管道的状态将文件移动到两个 GCS 存储桶之一 如果管道执行成功 则将文件移动到存储桶 A 否则 如果管道在执行过程中出现任何未处理的异常 则
  • Spring Data 与 Spring Data JPA 与 JdbcTemplate

    我有信心Spring Data and Spring Data JPA指的是相同的 但后来我在 youtube 上观看了一个关于他正在使用JdbcTemplate在那篇教程中 所以我在那里感到困惑 我想澄清一下两者之间有什么区别Spring
  • 反思 Groovy 脚本中声明的函数

    有没有一种方法可以获取 Groovy 脚本中声明的函数的反射数据 该脚本已通过GroovyShell目的 具体来说 我想枚举脚本中的函数并访问附加到它们的注释 Put this到 Groovy 脚本的最后一行 它将作为脚本的返回值 a la
  • 归并排序中的递归:两次递归调用

    private void mergesort int low int high line 1 if low lt high line 2 int middle low high 2 line 3 mergesort low middle l
  • 如何在 JFreeChart TimeSeries 图表上显示降雨指数和温度?

    目前 我的 TimeSeries 图表每 2 秒显示一个位置的温度 现在 如果我想每2秒显示一次降雨指数和温度 我该如何实现呢 这是我的代码 import testWeatherService TestWeatherTimeLapseSer
  • Java中未绑定通配符泛型的用途和要点是什么?

    我不明白未绑定通配符泛型有什么用 具有上限的绑定通配符泛型 stuff for Object item stuff System out println item Since PrintStream println 可以处理所有引用类型 通
  • 应用程序关闭时的倒计时问题

    我制作了一个 CountDownTimer 代码 我希望 CountDownTimer 在完成时重新启动 即使应用程序已关闭 但它仅在应用程序正在运行或重新启动应用程序时重新启动 因此 如果我在倒计时为 00 10 分钟 秒 时关闭应用程序
  • 使用 SAX 进行 XML 解析 |如何处理特殊字符?

    我们有一个 JAVA 应用程序 可以从 SAP 系统中提取数据 解析数据并呈现给用户 使用 SAP JCo 连接器提取数据 最近我们抛出了一个异常 org xml sax SAXParseException 字符引用 是无效的 XML 字符
  • 将 JSON 参数从 java 发布到 sinatra 服务

    我有一个 Android 应用程序发布到我的 sinatra 服务 早些时候 我无法读取 sinatra 服务上的参数 但是 在我将内容类型设置为 x www form urlencoded 之后 我能够看到参数 但不完全是我想要的 我在
  • Windows 上的 Nifi 命令

    在我当前的项目中 我一直在Windows操作系统上使用apache nifi 我已经提取了nifi 0 7 0 bin zip文件输入C 现在 当我跑步时 bin run nifi bat as 管理员我在命令行上看到以下消息 但无法运行
  • 将 JTextArea 内容写入文件

    我在 Java Swing 中有一个 JTextArea 和一个 提交 按钮 需要将textarea的内容写入一个带有换行符的文件中 我得到的输出是这样的 它被写为文件中的一个字符串 try BufferedWriter fileOut n
  • 中断连接套接字

    我有一个 GUI 其中包含要连接的服务器列表 如果用户单击服务器 则会连接到该服务器 如果用户单击第二个服务器 它将断开第一个服务器的连接并连接到第二个服务器 每个新连接都在一个新线程中运行 以便程序可以执行其他任务 但是 如果用户在第一个

随机推荐

  • STM8 学习笔记 5:时钟

    1 概述 时钟是单片机的脉搏 是单片机的驱动源 使用任何一个外设都必须打开相应的时钟 这样的好处是 如果不使用一个外设的时候 就把它的时钟关掉 从而可以降低系统的功耗 达到节能 实现低功耗的效果 每个时钟tick 系统都会处理一步数据 这样
  • 图数据库-Neo4j:linux centOS7安装

    1 下载 下载地址 社区版免费 https neo4j com download other releases releases 2 解压 tar axvf neo4j community 3 4 5 unix tar gz 3 修改配置文
  • 完全图解自然语言处理中的Transformer——BERT基础(入门长文)

    翻译自Jay Alammar Blog 在上一篇文章可视化Seq2Seq attention中 我们介绍了现在深度学习中特别常用的Attention 注意力 机制 注意力可以提升机器翻译的效果 这篇文章介绍Transformer 一种使用注
  • 深入理解Netty高性能网络框架

    大家好 今天我们来聊聊Netty的那些事儿 我们都知道Netty是一个高性能异步事件驱动的网络框架 它的设计异常优雅简洁 扩展性高 稳定性强 拥有非常详细完整的用户文档 同时内置了很多非常有用的模块基本上做到了开箱即用 用户只需要编写短短几
  • 平衡二叉树(AVL)python实现

    AVL树是一种特殊的二叉搜索树 BST树 数据极端情况下 二叉搜索树会退化成为单链表 但是AVL树通过旋转操作规避了这个问题 查找平均复杂度 O logn AVL树不适于删除的情况 class AVLTreeNode object def
  • Nginx 配置日志打印--HTTP报文

    http include mime types default type application octet stream log format main remote addr remote user time local request
  • loadrunner12——录制脚本时网络连接错误——无法弹出浏览器解决方法

    loadrunner12可以使用火狐浏览器 如果大家安装有问题 为了避免出错 可根据以下地址重新进行安装 https blog csdn net lmm0513 article details 87935863 1 首先打开loadrunn
  • 1到100, 中间随机抽走一个数,用算法得出是哪个数

    import java util ArrayList import java util HashMap import java util List import java util Map public class HunderTest p
  • UNIX环境高级编程 学习笔记 第二章 UNIX标准及实现

    C语言的ANSI标准在1989年得到批准 此标准也被采纳为国际标准ISO IEC 9899 1990 ANSI是美国国家标准学会 American National Standards Institute 它是国际标准化组织ISO Inte
  • 什么是全国大学生电子设计大赛?如何备战?

    前言 全国大学生电子设计竞赛是教育部和工业和信息化部共同发起的大学生学科竞赛之一 每一届都有非常多的大学生参加 但每届的比赛前夕 总会有很多同学并不清楚比赛的相关信息 流程以及如何去备战比赛 导致在比赛中出现准备不足或违法比赛规则等现象从而
  • C++--封装

    目录 封装 封装的含义 封装的意义1 实例一 实例二 C 面对对象的三大特点 继承 封装 多态 封装 封装的含义 将对象的属性和行为作为一个整体 表现生活中的事物 将属性和行为加以权限控制 封装的意义1 设计一个类 将属性和行为写到一起 表
  • Struts简介

    一 Struts英文单词意思 支柱 支架 来源于建筑和旧式飞机使用的金属支架 二 定义 Struts是流行和成熟的基于MVC设计模式的Web应用程序框架 Struts在软件开发中 是一个非常优秀的框架 它先是Jakarta项目的一个子项目
  • 微服务常见解决方案和高并发常见解决方案、以上特殊解决方案

    我确实比较懒 有些东西总是会写到自己的笔记本上或者在线笔记中 一般很少总结写到博客中 闲来无事确实总结了一些 如果你需要 可以私信聊聊 不敢说有特别好特别完美的方案 但是从个人视角结合知识再结合经验还是有点可说的内容的 如果你需要请私信
  • Parameter ‘name‘ not found. Available parameters are [0, 1, param1, param2]] with root cause

    SpringBoot环境 测试查询数据库 第一次直接通过dao层的注解查询 全局查询没问题 加入参数就报错了 提示说传的参数找不到 打印出来都有值 最后查了一下 这是错误的接口方法 查询注解里的参数有问题 修改为
  • TinyKv流程梳理三

    split流程 处理协程启动 func bs Raftstore startWorkers peers peer ctx bs ctx workers bs workers router bs router bs wg Add 2 raft
  • RecycleView

    鸿洋 Android RecyclerView 使用完全解析 体验艺术般的控件 http blog csdn net lmj623565791 article details 45059587 Android RecycleView 实现滑
  • 虚拟机服务器之间文件拷贝与传输

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 scp scp定义 scp可以实现服务器与服务器之间的数据拷贝 from server1 to server2 二 rsync rsync主要用于备份和镜
  • 开漏输出、推挽输出的区别

    前言 background 测试相关设备引脚输出 使用示波器时发现部分引脚需外接上拉电阻至高电平才能在示波器观察到高阻态 为了深究其中原理 查阅了相关资料 发现知乎中有一篇对这两种输出描述得清晰易懂的文章 此时才真正了解信号高阻态和高电平输
  • SpringBoot--基础--04--拦截器

    SpringBoot 基础 04 拦截器 拦截器 实现HandlerInterceptor接口 注册拦截器 一 代码结构 MyMvcConfig 使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能 Conf
  • 同步方法及同步代码块

    synchronized方法和synchronized块 synchronized方法必须获得对象的锁才能执行 否则线程阻塞 方法一旦执行 就独占此锁 直到方法返回才释放锁 后面被阻塞的线程才能获得这个锁 继续执行 synchronized