加入收藏 | 设为首页 | 会员中心 | 我要投稿 南通站长网 (https://www.0513zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

Java中怎样创建线程安全的技巧

发布时间:2021-11-18 18:18:02 所属栏目:教程 来源:互联网
导读:面试问题: 下面的方法是否线程安全?怎样让它成为线程安全的方法? class MyCounter { private static int counter = 0; public static int getCount() { return counter++; } } 本篇文章将解释一个常见的面试题,该问题被谷歌和很多其它公司问起过。它涉及

面试问题:
 
下面的方法是否线程安全?怎样让它成为线程安全的方法?
 
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中本地变量是线程安全的。
 
每一个线程都会有一个自己的栈,两个不同的线程是不会共享同一个栈的。
 
所有方法内部的本地变量将会在栈中分配空间,一旦当前线程的方法执行完毕,栈帧将马上被移除。

(编辑:南通站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读