zoukankan      html  css  js  c++  java
  • Java中怎样创建线程安全的方法

    面试问题:

    下面的方法是否线程安全?怎样让它成为线程安全的方法?

    class MyCounter {
        private static int counter = 0;
        public static int getCount() {
            return counter++;
        }
    }

    本篇文章将解释一个常见的面试题,该问题被谷歌和很多其它公司问起过。它涉及的相对比较初级,而不是关于怎样去设计复杂的并发程序。

    首先,这个问题的答案是No,因为counter++操作不是一个原子操作,而是由多个原子操作组成。

    举个例子,在如下情况:一个线程正在访问该数据,另一个线程正在执行递增操作;

    当线程Thread 1在t1时刻访问该方法,线程Thread 2有可能还没执行完这个方法的操作。因此,返回线程Thread 1的值有可能还没被递增过。

    使getCount方法成为线程安全-方式一

    使用关键字synchronized修饰getCount方法可以使它线程安全。当使用synchronized修饰静态方法,该类对象成为了锁。

    使用synchronized就足够了吗,答案是Yes.

    class MyCounter {
        private static int counter = 0;
        public static synchronized int getCount() {
            return counter++;
        }
    }

    如果方法不是静态方法,那么使用关键字synchronized同步的将是实例对象,而不是类对象。

    使getCount方法成为线程安全-方式二

    在这个特殊的计数例子里,通过使用java.util.concurrent.atomic包下的AtomicInteger原子类,可以使count++操作变成原子操作,如下。

    import java.util.concurrent.atomic.AtomicInteger;
    public class MyCounter {
        private static AtomicInteger counter = new AtomicInteger(0);
        public static int getCount() {
            return counter.getAndIncrement();
        }
    }

    其它一些有用的关于线程安全的事实

    在Java中本地变量是线程安全的。

    每一个线程都会有一个自己的栈,两个不同的线程是不会共享同一个栈的。

    所有方法内部的本地变量将会在栈中分配空间,一旦当前线程的方法执行完毕,栈帧将马上被移除。

    译文链接:http://www.programcreek.com/2014/02/how-to-make-a-method-thread-safe-in-java/

  • 相关阅读:
    django缓存机制
    RBAC基于角色访问控制
    Book系列十大接口
    xadmin的使用
    JWT认证
    自动生成接口文档
    drf的过滤排序分页异常处理
    认证权限解析频率
    python学习之内置模块补充
    python学习之内置模块补充作业
  • 原文地址:https://www.cnblogs.com/chenpi/p/5518264.html
Copyright © 2011-2022 走看看