分析现在公司AtomicLong应用代码
最近刚换工作,项目组人员很忙,没人理我,无事闲看代码,看的第一段代码,发现很有意思,特记录下来;
/** * 获取流水号 * * @return * @throws SerialGenneratorException */protected String getSerial() throws SerialGenneratorException {synchronized (serial) {//serial是AtomicLong类型long sn = serial.getAndIncrement();if (sn + 1 > this.getLimit()) {//如果达到上限,则更新上限serial.set(this.allocate());//更新上限sn = serial.getAndIncrement();}// System.out.println(Thread.currentThread().getId()+"------"+sn);return seiralFormat(sn, length);}}
自我分析后,很明显,改成以下代码,效率会成倍提高
protected String getSerial() throws SerialGenneratorException {long sn = serial.getAndIncrement();if (sn + 1 > this.getLimit()) {// 如果达到上限,则更新上限synchronized (serial) {// serial是AtomicLong类型if (sn + 1 > this.getLimit()) {// 如果仍然达到上限,则更新上限serial.set(this.allocate());// 更新上限sn = serial.getAndIncrement();}}}return seiralFormat(sn, length);}
1 楼 zhou2008gang 2012-01-11 如果是多线程来访问你的程序,会不会有问题?long sn = serial.getAndIncrement();
这个有没有同步? 2 楼 itao 2012-03-14 AtomicLong等类在实现同步时,没有用synchronized关键字,而是直接使用了最低层(本地c语言实现代码)来完成的。所以他本身是同步的,个人认为,不需要使用synchronized关键字就可以。 3 楼 jack547155187 2012-03-29 赞成2楼的意见 4 楼 XINRUIBAOBAO 2012-06-08 不赞同,2楼的意见,这种先检查再运行的代码最好还是要synchronized一下 5 楼 wml199039 2012-06-15 原子方法正是从指令层(并不是二楼所说的C语言)来解决同步问题的,
if (sn + 1 > this.getLimit()) 这句必须放在synchronized块中
因为可能会有两个线程“同时”执行该语句,这样就会导致业务错误 6 楼 wml199039 2012-06-15 itao 写道AtomicLong等类在实现同步时,没有用synchronized关键字,而是直接使用了最低层(本地c语言实现代码)来完成的。所以他本身是同步的,个人认为,不需要使用synchronized关键字就可以。
原子方法正是从指令层(并不是二楼所说的C语言)来解决同步问题的,
if (sn + 1 > this.getLimit()) 这句必须放在synchronized块中
因为可能会有两个线程“同时”执行该语句,这样就会导致业务错误