Java多线程并发去调用一个类的静态方法,会有问题吗?

java多线程中,对同一个类的静态方法加锁后,调用该方法,其他方法的调用会受到影响吗? 好记忆不如烂笔头, 能记下点什么, 就记下点什么, 方便后期的巩固 Spring介绍 Spring 是一个开源框架,是一个分层的 JavaEE 一站式框架。 所谓一站式框架是指 Spring 有 JavaEE 开发的每一层解决方案。 WEB层:SpringMVC Service层:Spring的Bean管理,声明式事务 DAO层:Spring的JDBC模板,ORM模板 优点: IOC:方便解耦合 ... 阅读详情
AI摘要

本文详细探讨了Java中多线程环境下静态方法的线程安全问题。通过对比实验揭示了静态方法是否会引起线程安全问题的关键因素,并展示了如何通过同步机制解决线程安全问题。

总的结论:java是线程安全的,即对任何方法(包括静态方法)都可以不考虑线程冲突,但有一个前提,就是不能存在全局变量。如果存在全局变量,则需要使用同步机制。

如下通过一组对比例子从头讲解:
在多线程中使用静态方法会发生什么事?也就是说多线程访问同一个类的static静态方法会发生什么事?是否会发生线程安全问题?

public class Test {
    public static void operation(){
        // ... do something
    }
}

事实证明只要在静态函数中没有处理多线程共享数据,就不存在着多线程访问同一个静态方法会出现资源冲突的问题。下面看一个例子:

public class StaticThread implements Runnable {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        StaticAction.print();
    }
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new StaticThread()).start();
        }
    }
}
public class StaticAction {
    public static int i = 0;
    public static void print() {
        int sum = 0;
        for (int i = 0; i < 10; i++) {
            System.out.print("step " + i + " is running.");
            sum += i;
        }
        if (sum != 45) {
            System.out.println("Thread error!");
            System.exit(0);
        }
        System.out.println("sum is " + sum);
    }
}

​ 实际执行的结果显示各个线程对静态方法的访问是交叉执行的,但是这并不影响各个线程静态方法print()中sum值的计算。也就是说,在此过程中没有使用全局变量的静态方法在多线程中是安全的,静态方法是否引起线程安全问题主要看该静态方法是否对全局变量(静态变量static member)进行修改操作。
​ 在多线程中使用同一个静态方法时,每个线程使用各自的实例字段(instance field)的副本,而共享一个静态字段(static field)。所以说,如果该静态方法不去操作一个静态成员,只在方法内部使用实例字段(instance field),不会引起安全性问题。
​ 但是,如果该静态方法操作了一个静态变量,则需要静态方法中采用互斥访问的方式进行安全处理。我们来看一下没有使用互斥访问的话会产生怎样的问题:

public class StaticAction {
    public static int i = 0;
    public static void incValue() {
        int temp = StaticAction.i;
        try {
            Thread.sleep(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        temp++;
        StaticAction.i = temp;
    }
}
public class StaticThread implements Runnable {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        StaticAction.incValue();
    }
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new StaticThread()).start();
        }
        try {
            Thread.sleep(1000);    //预留足够的时间让上面的线程跑完
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(StaticAction.i);
    }
}

实际运行结果显示i值为随机的数字。为了实现互斥访问,这时我们需要加入一个synchronized关键字。代码修改如下:

public class StaticAction {
    public static int i = 0;
    public synchronized static void incValue() {
        int temp = StaticAction.i;
        try {
            Thread.sleep(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        temp++;
        StaticAction.i = temp;
    }
}
public class StaticThread implements Runnable {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        StaticAction.incValue();
    }
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new StaticThread()).start();
        }
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(StaticAction.i);
    }
}

运行结果则必然是100。

加入synchronized关键字的静态方法称为同步静态方法。

​ 在访问同步静态方法时,会获取该类的“Class”对象,所以当一个线程进入同步的静态方法中时,线程监视器获取类本身的对象锁,其它线程不能进入这个类的任何静态同步方法。它不像实例方法,因为多个线程可以同时访问不同实例同步实例方法。这个其实就是操作系统中的用信号量实现进程的互斥与同步问题,如果涉及在同一个类中有多个静态方法中处理多线程共享数据的话,那就变成用信号量解决生产者-消费者问题。也就是说,静态方法是一份临界资源,对静态方法的访问属于进入临界区;对静态变量的修改是一份临界资源,对静态变量的修改属于进入临界区。

JNI native多线程调用Java静态方法 前言: 最近在做音视频实时通信,因为回声问题要解决,而播放和音视频采集是异步处理,所以需要java在中间做音频流桥接;播放端的音视频播放和拉流是在子线程处理的,因此有了这个应用场景。1.因为env不能多线程共享,而JavaVM可以,所以要通过在JNI入口c文件下把JavaVM保存起来,提供给其他线程使用,然后就可以在其他线程中通过JavaVM来拿到env;同时我也将java类设置为全局变量,供给其 阅读详情

相关推荐

多线程 - sleep和wait

【sleep和wait】

学无止境 1028

java多线程并发去调用一个类的静态方法安全性探讨

这篇文章主要讲多线程对静态方法访问的数据安全性 总结如下: 1,java在执行静态方法时,会在内存中拷贝一份,如果静态方法所在的类里面没有静态的变量,那么线程访问就是安全的,比如在javaee中服务器必然会多线程的处理请求此时如果设计全局需要调用的静态方法,可用此种设计。 2,java在执行静态方法时,如果使用静态变量,同事类的设计时使用到了静态数据,最好在调用函数时使用synchr

weibin_6388的专栏 2万+

MobaXterm详细使用教程

当然MobaXterm的功能远不止这些,但这些是最基本,最常用的,因此先拿出来讲。点击确定后,输入密码(输入密码时并不会显示,只管输入后按确定即可,第一次登陆成功后会提示保存密码,一般选择同意),就可以连接上虚拟机了。(2) 我们可以直接apt-get安装vim等常用功能(或者官网下载插件),实现在windows下模拟linux环境,这样就可以使用vi命令准备INCAR文件,也可以使用Gnuplot进行绘图。支持 Unix 命令(bash,ls,cat,sed,grep,awk,rsync,…

博客 4万+

Java多线程运行时,尽可能调用单例对象、工具类和静态方法,这样可以减少内存的占用量

前一段时间把我的项目发布到Production服务器上,经过一段时间跟踪发现服务器上项目的内存占有量在缓慢增长,但是我在本地做压力时却没有发现这个问题,或者虽然做了压力测试单由于环境的差异内存增长不明显所以没有注意。于是就下载了JProfilter安装到本地的测试服务器上(由于对Linux安装和配置不熟悉,费了不少时间),运行测试发现有些类的个数竟然大于并发线程的个数,很是奇怪,经分析发现原来这并

缥缈之心 5022

保姆级教程:用Docker Compose一键部署WVP-PRO+ZLM+录像服务(含Nginx反代)

本文提供了一套完整的容器化GB28181视频平台部署方案,通过Docker Compose实现WVP-PRO、ZLMediaKit(ZLM)和录像服务的一键式部署。详细介绍了环境准备、架构设计、容器化部署实战以及高级配置优化,帮助用户快速搭建高性能视频监控管理平台,适用于安防行业和物联网设备管理场景。

weixin_30415113的博客 861

深入解析AMBA5 AXI与ACE协议:从基础到高级应用

本文深入解析了AMBA5 AXI与ACE协议的核心机制与应用。AXI协议通过分离通道、突发传输和乱序完成实现高性能数据传输,而ACE协议在此基础上构建了硬件级缓存一致性解决方案,通过监听机制和状态模型确保多核系统数据统一。文章还探讨了在异构计算等复杂场景下的实战应用与AMBA5的新特性。

cc789的博客 963

多线中使用静态方法是否线程安全

静态变量,由于是在类加载时占用一个存储区,每个线程都是共用这个存储区的,所以如果在静态方法里使用了静态变量,这就会有线程安全问题!因为静态方法内声明的变量,每个线程调用时,都会新创建一份,而不会共用一个存储单元。静态方法如果没有使用静态变量,则没有线程安全问题。因此不会有线程安全问题。

码灵的博客 1502

【10. Wi-Fi 通用模组-小米 IoT 平台-如何进行硬件调试】

调试APP功能:从米家服务器缓存读取设备状态,等同于米家APP 的环境,开发者使用该调试器可模拟用户使用设备的实际情况,即调试米家 App 中的扩展程序。- 调试固件:调试器从固件读取设备状态,用于调试设备模组固件的某个单项功能,开发者使用该调试器可针对性地调试设备的某个功能。小爱语控测试工具:如果当前产品可被小爱语控,则可以使用该工具调试语控效果。调试APP功能(云端缓存)

tuoyuanO的博客 1041

多个线程调用静态方法,是否会出现并发问题?

多个线程调用静态方法,是否会出现并发问题取决于,静态方法内部是否需要引用共享区内的静态变量。当线程调用静态方法时,都会创建一套临时变量,可见性是在这个线程内部,所以当多个线程调用静态方法时,并且这个静态方法没有引用外部静态变量的。不会有线程并发的问题。

张少飞的优快云 1万+

ARM芯片内部的高速公路:手把手教你用AMBA Designer配置NIC-400互连控制器

本文详细介绍了如何使用AMBA Designer工具配置ARM芯片中的NIC-400互连控制器,涵盖从基础拓扑构建到高级QoS设置的完整流程。通过实际案例演示,帮助开发者掌握AXI协议下的高效片上网络设计,提升SoC性能与能效比。

weixin_26750481的博客 314

【YOLOv11改进- 主干网络】YOLOv11+RepViT: 从ViT的角度重新审视Mobile的CNN助力YOLOv11有效涨点;

本文给大家带来的改进内容是在YOLOv11中更换主干网络为RepViT,助力YOLOv11有效涨点,论文通过集成轻量级 ViT 的高效架构设计,逐步增强了标准轻量级 CNN(即 MobileNetV3)的移动友好性。这最终产生了一个新的纯轻量级 CNN 系列的主干网络。

qq_41304809的博客 786

java多线程并发去调用一个类的静态方法,会有问题吗?

总的结论:java是线程安全的,即对任何方法(包括静态方法)都可以不考虑线程冲突,但有一个前提,就是不能存在全局变量。如果存在全局变量,则需要使用同步机制。如下通过一组对比例子从头讲解: 在多线程中使用静态方法会发生什么事?也就是说多线程访问同一个类的static静态方法会发生什么事?是否会发生线程安全问题?public class Test { public static vo

Java那点事 | 学习●思考●分享 | Java技术交流QQ群:83753349 9908

【VibeCoding系列】小白入门指南:模型选择、编辑器选择、项目预定全分析

开箱即用:下载安装就能用,不用配 API Key(也可以自己配)Cmd+K 快速修改:选中代码,按 Cmd+K,直接让 AI 修改Cmd+L 对话:侧边栏聊天,支持引用文件和代码@文件引用:输入 @ 就能引用项目中的文件,AI 自动读取上下文Agent 模式:告诉 AI 一个需求,它自动跨文件修改下载地址cursor.com(免费版有额度限制,足够入门)✅下载 Cursorcursor.com),安装打开✅选一个小项目(个人名片页 or Todo List)✅按照七步工作流开干。

十年老程序猿,AI 疯狂研究专家,前沿硬核知识分享 212

多线程调用单例模式的类的同一个方法,是不是需要排队调用?

最近在研究多线程,突然想到一个问题,“多线程调用单例模式的类的同一个方法,是不是需要排队调用?”,比如有10个线程同时调用一个单例模式类的同一个方法,他们是第一个调完再轮到第二个调,还是10个线程同时可以调用这个方法?想出这种问题肯定是对java的基础知识掌握的不好,在网上找了很多帖子,但看下来都很懵懂,也发现有很多人和我有一样的问题,所以我自己写了代码,模拟这种情况,代码如下。1.单例模式的类p...

通往架构师之路 1万+

基于Simulink的间接功率控制的矩阵变换器

通过上述步骤,我们成功设计并实现了基于 Simulink 的间接功率控制的矩阵变换器仿真模型。该模型能够通过控制输入电流和输出电压,实现对功率的间接控制,适用于电机驱动、可再生能源系统、电力传输等领域。通过虚拟场景仿真、参数优化和性能评估,验证了系统的稳定性和高效性,并通过调整 PI 控制器参数和优化调制算法,进一步提升了系统的性能。

MHD0815的博客 296

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

用java定义一个学生类_JAVA 类的定义(定义一个类,来模拟“学生”)

package Code413;/*定义一个类,来模拟“学生”属性 (是什么)姓名年龄行为(能做什么)吃饭睡觉学习对应到Java的类当中成员变量(属性)String nanme; //姓名成员方法(行为)//成员方法不要staticpublic viod eat(){}public viod sleep(){}*/public class CodeStudent {//先写成员变量String...

weixin_39602280的博客 3589

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

JAVA中的多线程并发运行安全问题

JAVA中的多线程并发运行安全问题 1.什么是多线程并发运行安全问题? 当多个线程并发操作一个数据时,由于线程操作的时间不可控的原因,可能会导致操作该数据时的过程没有按照程序设计的执行顺序运行,导致操作后数据出现混乱,严重时可导致系统瘫痪。 2.用synchronized修饰的方法 当一个方法用synchronized修饰,那么该方法变为“同步方法“多个线程不能同时进入方法内容运行的,必须时有顺序的一个一个运行,这样就能避免并发安全问题。 案例:抢豆豆事件(使豆豆的剩余量不能为负数) public clas

weixin_47600732的博客 4874

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Java多线程并发安全问题

当多个线程并发操作同一临界资源,由于线程切换时机不确定,导致操作临界资源的顺序出现混乱严重时可能导致系统瘫痪.临界资源:操作该资源的全过程同时只能被单个线程完成.

是程序喵呀 1201

java 静态方法多线程

1、无论是用extends Thread还是implements Runnable,外面都需要包裹一层new Thread(); 2、同类的静态方法,本身是异步的。 3、同一类的多个synchronized static方法,共用一个锁,即synchronized修修饰的多个方法中,有任意一个在执行,所有synchronized方法都不能进入。 ThreadDemo代码: public class...

enthan809882的博客 1863

Java并发编程:理解多线程并发问题及其解决方法

java并发编程 多线程 解决方法 示例 锁 并发编程性能优化

weixin_40754174的博客 4736

java static静态方法的并发性

在做一个web项目的时候需要做一个通用类去处理一些问题,想到这个类很多地方都有用到,又不想每次都new一个,因此就定义了里面的方法是静态方法,然后又因为多个静态方法都用到了同一个对象,结果定义了一个类的全局变量让每个静态方法去调用它,刚开始没什么问题,后来项目上线没多久就挂了,最后发现这样做导致了多线程的并发问题,所以就想在这里记录一下… 下面是一个例子,例如: public cla...

b507257377457396的博客 255
上一篇: Linux定时删除文件
下一篇: 多线程并发变量问题
金陵张大炮
博客等级 码龄9年 30粉丝 86原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值