面试问题:

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

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/

Java中怎样创建线程安全的方法的更多相关文章

  1. Java中如何创建线程

    Java中如何创建线程 两种方式:1)继承Thread类:2)实现Runnable接口. 1.继承Thread类 继承Thread类,重写run方法,在run方法中定义需要执行的任务. class M ...

  2. 如何在Java中编写一个线程安全的方法?

    线程安全总是与多线程有关的,即一个线程访问或维护数据时遭到了其它线程的“破坏”,为了不被破坏,就要保持所维护变量的原子性: 1 局部变量总是线程安全的,因为每个线程都有自己的栈,而在方法中声明的变量都 ...

  3. Java中的后台线程和join方法

    /*守护线程(后台线程):在一个进程中如果只剩下 了守护线程,那么守护线程也会死亡. 需求: 模拟QQ下载更新包. 一个线程默认都不是守护线程. */ public class Demo extend ...

  4. Java中如何创建进程(转)

    在Java中,可以通过两种方式来创建进程,总共涉及到5个主要的类. 第一种方式是通过Runtime.exec()方法来创建一个进程,第二种方法是通过ProcessBuilder的start方法来创建进 ...

  5. Java并发--如何创建线程

    下面是本文的目录大纲: 一.Java中关于应用程序和进程相关的概念 二.Java中如何创建线程 三.Java中如何创建进程 转载原文链接:http://www.cnblogs.com/dolphin0 ...

  6. Java中的守护线程 & 非守护线程(简介)

    Java中的守护线程 & 非守护线程 守护线程 (Daemon Thread) 非守护线程,又称用户线程(User Thread) 用个比较通俗的比如,任何一个守护线程都是整个JVM中所有非守 ...

  7. Java中的五种单例模式实现方法

    [代码] Java中的五种单例模式实现方法   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 2 ...

  8. Java中产生随机数的两个方法

    Java中产生随机数的两个方法 一.利用random方法来生成Java随机数. 在Java语言中生成Java随机数相对来说比较简单,因为有一个现成的方法可以使用.在Math类中,Java语言提供了一个 ...

  9. Java 中能创建 volatile 数组吗?

    能,Java 中可以创建 volatile 类型数组,不过只是一个指向数组的引用,而不 是整个数组.我的意思是,如果改变引用指向的数组,将会受到 volatile 的保护, 但是如果多个线程同时改变数 ...

随机推荐

  1. Winform 显示Gif图片

    代码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data ...

  2. Win10怎么输入法切换

    按 windows 键+空格键,或者CTRL+Shift,或者只按 Shift,或者CTRL+空格 试试 方法/步骤1在桌面上点击[控制面板],进入控制面板后使用分类显示控制面板内的选项.然后在语言下 ...

  3. asp.net(c#)将彩色图片变灰阶图片

    代码如下: using System; using System.Collections; using System.Configuration; using System.Data; using S ...

  4. MVC之前的那点事儿系列(1):进入CLR

    MVC之前的那点事儿系列,是笔者在2012年初阅读MVC3源码的时候整理的,主要讲述的是从HTTP请求道进入MVCHandler之前的内容,包括了原创,翻译,转载,整理等各类型文章,当然也参考了博客园 ...

  5. adb 常用命令总结

    1. adb / adb -help 使用帮助 2. adb devices 查看连接到电脑的设备 3. adb install example.apk 安装程序 4. adb -s emulator ...

  6. web iis服务器安全性配置实例

    自己不维护服务器,不知道维护服务器的辛苦.刚开始为了嫌麻烦,抱有侥幸心理,一些繁琐的安全设置没有配置,结果服务器连一天都没撑过去.经过10天的反复摸索和努力,现在服务器已经稳定工作一个月了,特此整理本 ...

  7. HTML5 Canvas 实现的9个 Loading 效果

    Sonic.js 是一个很小的 JavaScript 类,用于创建基于 HTML5 画布的加载图像.更强大的是 Sonic.js 还提供了基于现成的例子的创建工具,可以帮助你实现更多自定义的(Load ...

  8. 知道吗?9个搜索引擎优化(SEO)最佳实践

    作为网页设计师,搜索引擎优化重要吗?我们知道,网站设计是把屏幕上平淡无奇变成令人愉快的美感,更直观地辨认信息.这也是人与人之间在沟通想法,这样的方式一直在演变.穴居人拥有洞穴壁画,古埃及人有象形文字, ...

  9. angularjs封装bootstrap官网的时间插件datetimepicker

    背景:angular与jquery类库的协作 第三方类库中,不得不提的是大名鼎鼎的jquery,现在基本上已经是国内web开发的必修工具了.它灵活的dom操作,让很多web开发人员欲罢不能.再加上已经 ...

  10. JavaScript强化教程——jQuery UI API 类别

    ---恢复内容开始--- 主要介绍:JavaScript强化教程​—— jQuery UI API 类别 jQuery UI 在jQuery 内置的特效上添加了一些功能.jQuery UI 支持颜色动 ...