静态变量的多线程同步问题

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

我们先来讨论一个问题,一个类的静态变量当类被多次实例化的时候,静态变量是否会受影响?首先我们应该清楚的是静态变量是在类被JVM classloader的时候分配内存,并且是分配在永久区而非堆内存中。

当我们用对象锁来同步静态变量的时候,我们来看一个例子。

public interface OrderService {public String getOrderNo();
}

先定义一个接口,获取一个订单编号。

public class OrderLockServiceImpl implements OrderService {static int num = 0;
    @Override
    synchronized public String getOrderNo() {SimpleDateFormat date = new SimpleDateFormat("YYYYMMDDHHMMSS");
        return date.format(new Date()) + num++;
    }
}

实现这个接口,并且用对象方法来操作静态变量。

public class OrderTask implements Runnable {private CountDownLatch latch;
    private OrderService orderService;
    public OrderTask(CountDownLatch latch,OrderService orderService) {this.latch = latch;
        this.orderService = orderService;
    }@Override
    public void run() {try {latch.await();
        } catch (InterruptedException e) {e.printStackTrace();
        }System.out.printf("线程名%s订单号:%s\n",Thread.currentThread().getName(), orderService.getOrderNo());
    }
}

创建一个线程类,使用CountDownLatch来让每一个线程都有出现的机会,而不是某一个线程独占。

public static void main(String[] args) {
   ExecutorService service = Executors.newCachedThreadPool();
   final CountDownLatch latch = new CountDownLatch(1);
   for (int i = 0;i < 10;i++) {OrderService orderService = new OrderLockServiceImpl();
      service.submit(new OrderTask(latch,orderService));
   }latch.countDown();
   service.shutdown();
}

最后实现main方法,用线程池来提交10次线程任务。结果我们发现,这个静态变量会出现重复(并不是每一次运行都会重复)

线程名pool-2-thread-1订单号:20180719619072331
线程名pool-2-thread-7订单号:20180719619072337
线程名pool-2-thread-3订单号:20180719619072337
线程名pool-2-thread-9订单号:20180719619072336
线程名pool-2-thread-5订单号:20180719619072335
线程名pool-2-thread-6订单号:20180719619072334
线程名pool-2-thread-10订单号:20180719619072333
线程名pool-2-thread-4订单号:20180719619072330
线程名pool-2-thread-2订单号:20180719619072332
线程名pool-2-thread-8订单号:20180719619072338

由此我们可以断定,对象锁并不能保证静态变量的同步安全。不过如果对象在堆内存中是唯一的,如

public static void main(String[] args) {
   ExecutorService service = Executors.newCachedThreadPool();
   final CountDownLatch latch = new CountDownLatch(1);
   OrderService orderService = new OrderLockServiceImpl();
   for (int i = 0;i < 10;i++) {service.submit(new OrderTask(latch,orderService));
   }latch.countDown();
   service.shutdown();
}

则无论你运行多少次,则静态变量也一定是同步的。

但是如果我们使用的是类锁,来改进上面的代码。

public abstract class AbstractOrderService implements OrderService {static int num = 0;
    public static synchronized String getOrderNo2() {SimpleDateFormat date = new SimpleDateFormat("YYYYMMDDHHMMSS");
        return date.format(new Date()) + num++;
    }@Override
    public String getOrderNo() {return getOrderNo2();
    }
}

抽象类中使用静态方法,来同步静态变量。

public class OrderLockServiceImpl extends AbstractOrderService {}

我们在子类中什么都不做,只继承于抽象类

此时我们即便实例化10个对象

for (int i = 0;i < 10;i++) {OrderService orderService = new OrderLockServiceImpl();
   service.submit(new OrderTask(latch,orderService));
}

其结果依然无论运行多少次,都不会出现重复订单号,因为这里已经使用了类锁来同步静态变量。

转载于:https://my.oschina.net/u/3768341/blog/1854233

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/451182.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

extends和implements区别

extends和implements区别 extends与implements的不同 1、在类的声明中&#xff0c;通过关键字extends来创建一个类的子类。 一个类通过关键字implements声明自己使用一个或者多个接口。 extends 是继承某个类, 继承之后可以使用父类的方法, 也可以重写父类的方法; imple…

评论:电商巨头们谁有勇气晒晒“价格战”账单?

摘要&#xff1a;国内电商接二连三上演的“价格战”&#xff0c;点燃了消费者的购买热情。在笔者看来&#xff0c;如果有哪个大型电商有勇气亮出价格战账单&#xff0c;那对竞争对手的刺激和打击效果将非同一般。晒出了账单后&#xff0c;消费者对购物场所的选择也将一目了然&a…

The xxx collides with a package/type

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 当类和包&#xff0c;重名时&#xff0c;包会报错误&#xff1a;The package aaa.a collides with a type&#xff1b;类也会报警告&…

Hive 行列转换

在京东众多业务中&#xff0c;促销业务充满了复杂性和挑战性&#xff0c;因为业务的灵活性&#xff0c;很多数据都存储成xml和json格式数据&#xff0c;这就要求下游数据分析师们需要对其做解析后方可使用 。 在众多操作中 &#xff0c;有一种是需要对数据做行列转换操作。 数据…

[译] 论 Rust 和 WebAssembly 对源码地址索引的极限优化

原文地址&#xff1a;Oxidizing Source Maps with Rust and WebAssembly原文作者&#xff1a;Nick Fitzgerald译文出自&#xff1a;掘金翻译计划本文永久链接&#xff1a;github.com/xitu/gold-m…译者&#xff1a;D-kylinTom Tromey 和我尝试使用 Rust 语言进行编码&#xff0…

Java WebService 简单实例

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 前言&#xff1a;朋友们开始以下教程前&#xff0c;请先看第五大点的注意事项&#xff0c;以避免不必要的重复操作。 一、准备工作&…

互联网侵入手机逐鹿背后:追求流量变现能力

摘要&#xff1a;小米联合创始人黎万强说&#xff0c;卖出10万台得免速死&#xff0c;卖出百万台算是得到了一张正式入行的门票。小米是一家新创公司&#xff0c;黎万强自己说&#xff0c;原本一无所有&#xff0c;作为原创品牌&#xff0c;它选择了口碑之路&#xff0c;则必须…

java api使用ElastichSearch指南

AggregationBuilders.terms:一段时间内&#xff0c;某个字段取值的数量排名前几的聚合 / ** param startTime 开始的时间* param endTime 结束的时间* param termAggName term过滤* param fieldName 要做count的字段* param top 返回的数量*/ RangeQueryBuilder actionPeriod …

关于JavaScript的数组随机排序

昨天了解了一下Fisher–Yates shuffle费雪耶兹随机置乱算法&#xff0c;现在再来看看下面这个曾经网上常见的一个写法&#xff1a; function shuffle(arr) { arr.sort(function () { return Math.random() - 0.5; }); } 或者使用更简洁的 ES6 的写法&#xff1a; function shu…

通用唯一识别码UUID

UUID是通用唯一识别码&#xff08;Universally Unique Identifier&#xff09;的缩写。UUID 的目的&#xff0c;是让分布式系统中的所有元素&#xff0c;都能有唯一的辨识资讯&#xff0c;而不需要透过中央控制端来做辨识资讯的指定。如此一来&#xff0c;每个人都可以建立不与…

java内省机制 + 内省是什么 + 内省实现方式 + 和反射的区别

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、内省是什么、实现方式&#xff1a; 内省&#xff08;Introspector&#xff09;是Java语言对Bean类属性、事件的一种缺省处理方法。…

百度联合长虹发布第二款云手机 售价900元以下

摘要&#xff1a;【搜狐IT消息】5月15日消息&#xff0c;百度今天宣布联合长虹发布第二款智能手机&#xff0c;采用3.5英寸屏幕、300万像素摄像头&#xff0c;650MHz主频处理器&#xff0c;零售价格在700-899元之间&#xff0c;中国联通将为其提供话费补贴。 【搜狐IT消息】5月…

vmware workstation17环境安装centos7

打开控制面板&#xff0c;搜索“服务”&#xff0c;启动vmware authorize service -------解决无法开启虚拟机问题之无法连接MKS 2.虚拟机硬盘扩展为15G------解决安装centos7时出现的“检查存储配置出错”问题 3.硬盘分区----/boot 300mb&#xff08;不能小于200mb&#xff0…

博客园中的源代码格式显示

昨天写了一篇文章&#xff0c;但是在写的时候呢&#xff0c;没有注意&#xff0c;直接将代码复制上去了&#xff0c;今天正好有人提醒&#xff0c;看到了格式的混乱&#xff0c;借此记录整理一下&#xff0c;如何能直接粘贴代码&#xff0c;而且格式&#xff08;缩进&#xff0…

static的使用

类中的静态变量在程序运行期间&#xff0c;其内存空间对所有该类的对象实例而言是共享的&#xff0c;为了节省系统内存开销、共享资源&#xff0c;应该对一些适合使用static的变量声明为静态变量。 变量声明为static的使用场景&#xff1a; &#xff08;1&#xff09;变量所…

Linux内核的裁剪和移植

linux内核的裁剪和移植具体都在这个网址里面。https://blog.csdn.net/xie0812/article/details/10816059https://blog.csdn.net/xie0812/article/details/10821779转载于:https://blog.51cto.com/13401435/2145947

李开复唱衰互联网手机:大部分公司会失败

摘要&#xff1a;互联网企业和手机制造企业之间巨大的鸿沟也被李开复鲜明地指出来&#xff1a;“两个产业差别巨大&#xff0c;企业基因不同。”百度此前也坦诚表示&#xff0c;与长虹合作的千元机&#xff0c;主要是针对2000元以下的用户体验&#xff0c;不能与四五千元的苹果…

【POJ】3268 Silver Cow Party

题目链接&#xff1a;http://poj.org/problem?id3268 题意 &#xff1a;有N头奶牛&#xff0c;M条单向路。X奶牛开party&#xff0c;其他奶牛要去它那里。每头奶牛去完X那里还要返回。去回都是走的最短路。现在问这里面哪头奶牛走的路最长。 题解&#xff1a;对每个奶牛i与X做…

java.util.ConcurrentModificationException异常分析

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Java在操作ArrayList、HashMap、TreeMap等容器类时&#xff0c;遇到了java.util.ConcurrentModificationException异常。以ArrayList为例…

redis基本数据类型之String

redis基本数据类型之String redis一共分为5中基本数据类型&#xff1a;String,Hash,List,Set,ZSet String String类型是包含很多种类型的特殊类型&#xff0c;并且是二进制安全的。比如序列化的对象进行储存&#xff0c;比如一张图片进行二进制储存&#xff0c;比如一个简单…