面试问题:

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

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/

转载于:https://www.cnblogs.com/chenpi/p/5518264.html

Java中怎样创建线程安全的方法相关推荐

  1. 【java】Java 中的 Exchanger 线程同步使用方法 线程之间交换数据

    1.概述 转载:https://www.pdai.tech/md/java/thread/java-thread-x-juc-tool-exchanger.html 视频参考:https://www. ...

  2. java中怎样创建线程_java中的线程创建和使用

    Java中实现多线程有两种途径:继承Thread类或者实现Runnable接口.Runnable是接口,建议用接口的方式生成线程,因为接口可以实现多继承,况且Runnable只有一个run方法,很适合 ...

  3. Java中枚举的线程安全性及序列化问题

    转载自  Java中枚举的线程安全性及序列化问题 Java SE5提供了一种新的类型-Java的枚举类型,关键字enum可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序 ...

  4. 什么是Java中的守护程序线程?

    谁能告诉我Java中有哪些守护程序线程? #1楼 守护程序线程就像其他与守护程序线程在同一进程中运行的线程或对象的服务提供者一样. 守护程序线程用于后台支持任务,仅在执行正常线程时才需要. 如果正常线 ...

  5. [转载] java中对象作为参数传递给一个方法,到底是值传递,还是引用传递

    参考链接: 用Java传递和返回对象 看完绝对清晰~ java中对象作为参数传递给一个方法,到底是值传递,还是引用传递? pdd:所谓java只有按值传递:基本类型  值传递:引用类型,地址值传递,所 ...

  6. Java中的守护程序线程

    Daemon thread in java can be useful to run some tasks in background. When we create a thread in java ...

  7. python创建类的实例方法-Python中动态创建类实例的方法

    简介 在Java中我们可以通过反射来根据类名创建类实例,那么在Python我们怎么实现类似功能呢? 其实在Python有一个builtin函数import,我们可以使用这个函数来在运行时动态加载一些模 ...

  8. Java中如何实现线程的超时中断

    转载自  Java中如何实现线程的超时中断 背景 之前在实现熔断降级组件的时候,需要实现接口请求的超时中断.意思是,业务在使用熔断降级功能时,在平台上设置了一个超时时间,如果请求进入熔断器开始计时,接 ...

  9. Java中的length字段和length()方法

    本文主要讲述Java中的length字段和length()方法,有需要的朋友可以参考下,更多Java教程知识,请登陆疯狂软件教育官网. 首先,你能快速回答下面的问题吗? 如果没有IDE(集成开发环境) ...

最新文章

  1. 计算机行业可以开安装服务费,安装服务费税率是多少
  2. rust狗阳玩的什么游戏_微博搜索
  3. mysql发生系统错误2系统找不到指定文件_电脑运行错误代码大全,遇到报错请自己对照断电原因所在吧...
  4. 开发日记-20190815 关键词 读书笔记《Linux 系统管理技术手册(第二版)》DAY 23
  5. Asp.net中的Cache--HttpRuntim.Cache 和 HttpContext.Current.Cache
  6. 设计模式示例_代理设计模式示例
  7. C#设计模式之16-迭代器模式
  8. 2017.4.19 多项式输出 思考记录
  9. k8s与监控--从telegraf改造谈golang多协程精确控制
  10. iOS TableView性能优化
  11. VBA字典对象操作技巧
  12. 自组织映射 (SOM) 解决旅行商问题 (TSP)
  13. 沈海高速汕尾往深圳服务器维护报价,沈海高速收费
  14. mysql leader/followers_half-sync/half-async 和 Leader/Followers 模式的主要区别
  15. git 主干修改合并到分支_git分支与主干合并操作
  16. Python:NBA球员得分数据排行爬虫
  17. 给程序员新年巨献:Google最热门60款开源项目
  18. Android 双u盘方案
  19. wireshark 学习更进一步 之RST数据解读
  20. 《炬丰科技-半导体工艺》多孔硅的冲洗和干燥研究

热门文章

  1. 初学css list-style属性
  2. Django之Cookie
  3. sharepoint2013保存当前输入的列表
  4. 学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装
  5. APP中的悬浮球设计总结
  6. 如何跟各种人解释什么是产品经理
  7. 11张图让你看完苹果发布会
  8. 【分析】立即购买vs加入购物车,移动电商购买流程差异分析
  9. 一个插排引发的设计思想 (三) 委托与事件
  10. [验证码识别技术]字符验证码杀手--CNN