7.2 在Java中如何让一个方法线程安全

面试题目:
下面的方法是线程安全吗?如果让它变为线程安全?

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

这篇文章来解释一个常被Google和其他许多公司问到的面试题目。它是低级的,与如何设计并发程序无关。

首先,答案是否定的。这个方法不是线程安全的,因为counter++操作不是原子的,这意味着它由超过一个原子操作组成。这个例子中,一个是访问值,一个是在这个值上增加1.

计数器增加

当线程1在t1时间访问这个方法的时候,线程2 也许还没完成这个方法。所以在线程1中被返回的值是没有被增加的值。

使线程安全-方法1

在这个方法上添加synchronized将使它线程安全。当synchronized添加在一个静态方法时,Class对象是被锁定的对象。
标记方法是否足够同步?答案是Yes。

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

如果方法不是静态的,添加synchronized关键字将同步这个类的实例而不是类对象本身。

使线程安全-方法二

在这个特别例子中,我们实际上可以通过使用"java.util.concurrent.atomic"包中的AutomicInteger来创建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中是线程安全的。

每个线程都有自己的栈。两个不同的线程不共享相同的栈。所有在方法中定义的本地变量都在栈中被分配内存。一旦当前线程完成,堆栈帧将被删除。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,572评论 11 349
  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 9,200评论 0 11
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 33,737评论 18 399
  • 点击这里查看视频 我是Wind, 以前是字幕组组长. 我每天早上听写1分钟电影, 已经坚持100天了, 今天立个f...
    Wind教口语阅读 2,839评论 1 5
  • 那时我们有梦,关于文学,关于爱情,关于穿越世界的旅行。如今我们深夜饮酒,杯子碰到一起,都是梦破碎的声音。——北岛 ...
    林景然阅读 2,833评论 0 0

友情链接更多精彩内容