`

Static工具类线程安全问题

 
阅读更多
1.静态方法
    无论是静态方法还是实例方法,在内存中都只有一份代码,也就是只占用一份内存空间
方法属于一个程序块,只有当别人调用它时才会调到内存里面去执行,也就是说当前有多少个线程在执行就有多少组方法块里的局部变量

2.静态变量
    只存在一份,多个线程公用一份,一个线程修改就会影响其他线程

3.结论
   静态方法是使用得当是线程安全的,因为每次调用会创建一份私有块,如果是静态变量是的的话就要加锁挥着其他处理。

4.实例

class User{
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public class StaticTest {
    private static int count = 0;
    private static int counts = 0;

    /**
     * 不会存在并发问题
     *
     * @return
     */
    public static String getTestStr() {
        String xx = Thread.currentThread().toString();
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return xx;
    }

    /**
     * 存不存在并发问题与传入的变量有关
     * 假如thread a和thread b都在操作对象a则存在
     * @param user
     * @return
     */
    public static String getTestUser(User user) {
        String str = "id: " + user.getId() + "name: " + user.getName();
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return str;
    }

    /**
     * 存在并发问题
     *
     * @return
     */
    public static int getTestCount() {
        count++;
        count++;
        count++;
        count++;
        count++;
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        count++;
        count++;
        count++;
        count++;
        count++;
        return count;
    }

    /**
     * 不存在并发问题
     *
     * @return
     */
    public synchronized static int getTestCountS() {
        counts++;
        counts++;
        counts++;
        counts++;
        counts++;
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        counts++;
        counts++;
        counts++;
        counts++;
        counts++;
        return counts;
    }

    public static void main(String[] args) {
        User user = new User();
        for (int i = 0 ; i < 1000 ; i++){
            final int finalI = i;
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    User userTmp = new User();
                    user.setId(finalI);
                    user.setName(Thread.currentThread().toString());
                    userTmp.setId(finalI);
                    userTmp.setName(Thread.currentThread().toString());
                    //局部变量不存在问题
                    System.out.println("getTestStr: " + Thread.currentThread()  + StaticTest.getTestStr());
                    //与user有关
                    System.out.println("getTestUser: " + Thread.currentThread() + StaticTest.getTestUser(user));
                    System.out.println("getTestUseS: " + Thread.currentThread()  + StaticTest.getTestUser(userTmp));

                    //线程不安全
                    System.out.println("getTestCount: "  + Thread.currentThread() + StaticTest.getTestCount() % 10);

                    //安全但是慢需要加锁
                    System.out.println("getTestCountS: "  + Thread.currentThread() + StaticTest.getTestCountS() % 10);
                }
            });
            thread.start();
        }


    }
}
分享到:
评论

相关推荐

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

    在上述代码中,可以使用`synchronized`关键字修饰`test()`方法,或者使用`AtomicInteger`等并发类来替代`int`,以避免线程安全问题。 ```java public static synchronized void test(int param) { System.out....

    浅议单例模式之线程安全(转)

    在懒汉式的基础上添加了同步锁,避免了线程安全问题。 ```java public class Singleton { private volatile static Singleton INSTANCE; private Singleton() {} public static Singleton getInstance() {...

    Java多线程-线程安全问题练习题

    在Java多线程编程中,线程安全问题是非常关键的概念,它涉及到多个线程访问共享资源时可能出现的数据不一致或异常情况。本题主要通过两个练习题来加深对线程安全的理解。 ### 练习题1:新年倒计时 #### 题目描述 ...

    Java并发中的线程安全性

    5. **利用并发工具类**:Java并发库提供了许多工具类,如`AtomicInteger`、`ConcurrentHashMap`等,可以帮助开发者更容易地编写线程安全的代码。 总之,理解线程安全的概念对于开发高效、可靠的多线程Java应用程序...

    使用C++11实现线程安全的单例模式

    `std::mutex` 不是直接使用,因为`std::call_once`已经处理了线程安全问题。 在`main.cpp` 文件中,你可以使用这个单例来执行相关操作。例如: ```cpp #include "singleton.h" int main() { Singleton& s1 = ...

    Java 单例模式 工具类

    本篇文章将深入探讨如何在Java中实现单例模式,以及如何创建一个工具类来封装单例的创建。 首先,让我们了解单例模式的几种常见实现方式: 1. 饿汉式(静态常量): 这是最简单的单例实现,它在类加载时就完成了...

    线程安全总结.doc

    `ThreadLocal`是一种特殊的变量类型,它可以为每个线程提供一个独立的副本,从而避免了线程间的共享,简化了线程安全问题的处理。 #### 测试工程 最后,为了验证线程安全性的实现,可以通过编写单元测试来模拟多...

    关于SimpleDateFormat的非线程安全问题及其解决方案.docx

    ### 关于SimpleDateFormat的非线程安全问题及其解决方案 #### 一、问题介绍 在Java开发过程中,`SimpleDateFormat`是被广泛使用的日期格式化工具类。然而,在多线程环境下,`SimpleDateFormat`存在非线程安全的...

    java utils 工具类

    - **线程安全**:如果工具类的方法可能在多线程环境下使用,确保它们是线程安全的。 - **异常处理**:提供合理的异常处理策略,避免抛出未经检查的异常。 ### 5. 示例代码分析 ```java public class ProcessUtil {...

    线程问题出现与解决

    - **同步代码块**:通过`synchronized`关键字将可能引起线程安全问题的代码段标记为同步代码块。 - **同步方法**:在方法定义前加上`synchronized`关键字,使整个方法成为同步方法。 - **使用`volatile`关键字**:...

    多线程的小例子,线程互斥的问题

    1. **Mutex类**:`Mutex`是C#中实现线程互斥的工具之一。它为全局资源提供独占访问,任何时刻只有一个线程能持有Mutex。当一个线程获取Mutex后,其他尝试获取的线程会被阻塞,直到Mutex被释放。以下是一个简单的...

    Android SP存储工具类

    本篇将详细讲解如何创建一个SP存储的工具类,以便于在项目中进行增删改查的操作。 首先,我们需要创建一个名为`SharedPreferencesUtil`的工具类,这个类通常包含静态方法,因为它们不需要实例化对象就可以直接调用...

    工具类utils.rar

    由于工具类中的方法通常是静态的,因此需要注意线程安全问题。如果一个工具类的方法修改了共享状态或依赖于外部状态,那么必须确保方法是线程安全的,或者明确说明其非线程安全以防止误解。 6. **异常处理**: ...

    java枚举是如何保证线程安全的

    Java枚举类型自Java SE5引入以来,成为了保证线程安全的一种强大工具。在Java中,枚举是一种特殊的类,由编译器自动处理并确保其线程安全性。以下是关于Java枚举线程安全的详细解释。 首先,枚举类型在Java中实际上...

    jedis工具类

    为了确保线程安全,通常会使用`synchronized`关键字或线程局部变量来管理Jedis实例。 总之,Jedis工具类是Java开发者与Redis进行交互的重要桥梁,通过封装常用的操作,使得在项目中使用Redis变得更加便捷和高效。...

    java练手全程录4-处理工具类代码实现

    3. **无状态**:工具类不应持有任何状态(成员变量),确保其方法的独立性和线程安全性。 4. **命名规范**:方法名应清晰地反映出其功能,如`printArray()`或`convertStringToInteger()`。 在描述中提到的链接可能...

    详解SimpleDateFormat的线程安全问题与解决方案

    本文将深入探讨`SimpleDateFormat`的线程安全问题及其解决方案。 ### 1. 线程安全问题的原因 `SimpleDateFormat`内部维护了一个`Calendar`对象,用于处理日期和时间的解析与格式化。由于`SimpleDateFormat`不是...

    ActiveMQ连接池完整封装实例工具类

    6. **线程安全**:由于多个线程可能同时访问工具类,因此需要确保所有方法都是线程安全的。这可以通过同步块或者使用线程安全的数据结构实现。 7. **异常处理**:工具类应该包含适当的异常处理机制,以便在出现问题...

    使用内部类实现线程

    在Java编程语言中,线程是程序执行的最小单元,它可以与程序中的其他线程并发运行。本篇文章将深入探讨如何使用...在实际应用中,我们还需要考虑线程安全、同步机制以及线程池等高级主题,以确保程序的正确性和性能。

Global site tag (gtag.js) - Google Analytics