java static方法 引用static属性 存在线程安全问题-原理分析

Ella ·
更新时间:2024-11-10
· 693 次阅读

java static方法 引用static属性 存在线程安全问题-原理分析 测试代码 package javabase.src.thread; public class StaticMethodTest { private static int a = 0; public static void main(String[] args) { new Thread(StaticMethodTest::run, "thread1").start(); new Thread(() -> run2(), "thread2").start(); } public static void test(int param) throws InterruptedException { System.out.println("==============="+Thread.currentThread().getName()+"操作之前的a值:"+a+"==================="); // 先让 线程进行操作之前 都能 先拿值(造成线程安全问题) Thread.sleep(1000); a += param; System.out.println("==============="+Thread.currentThread().getName()+"进行加"+param+"操作之后的a值:"+a+"============="); } private static void run() { try { test(1); } catch (InterruptedException e) { e.printStackTrace(); } } private static void run2() { try { // 目的 : 等待 其他线程执行完毕后在执行 // 让执行此业务的 线程 先sleep 1秒 Thread.sleep(1000); test(2); } catch (InterruptedException e) { e.printStackTrace(); } } } 运行结果 ===============thread1操作之前的a值:0=================== ===============thread2操作之前的a值:0=================== ===============thread1进行加1操作之后的a值:1============= ===============thread2进行加2操作之后的a值:3============= 结果分析:

通过结果我们很容易看出问题所在

​ thread1和thread2 进行运算之前获取的值都是 0

​ thread1:0 + 1 = 1 结果正确

​ thread2:0 + 2 = 3 结果错误

原理分析

​ static修饰的属性 在JVM 内存中是存储在 方法区中,全局使用的此属性 只有一份

为了保证两个线程都是 先取值 再运算

使用Thread.sleep(1000);进入TImed-waitting 状态(线程具体状态及源码解析详见

线程-Thread类源码解析及线程状态分析

public static void test(int param) throws InterruptedException { System.out.println("==============="+Thread.currentThread().getName()+"操作之前的a值:"+a+"==================="); // 先让 线程进行操作之前 都能 先拿值(造成线程安全问题) Thread.sleep(1000); a += param; System.out.println("==============="+Thread.currentThread().getName()+"进行加"+param+"操作之后的a值:"+a+"============="); } thread1执行test(1)之后 现在 thread2方法栈中 a的值 也已经改变, private static void run() { try { test(1); // 代码执行到此处时 a 的值 已经变成了 1 } catch (InterruptedException e) { e.printStackTrace(); } }

note: 文章用于学习交流,如有错误之处,请大家指正


作者:_腊月十四



JAVA 线程安全 static 线程

需要 登录 后方可回复, 如果你还没有账号请 注册新账号