济南做网站 推荐行知科技,深圳市做网站知名公司有哪些,网页设计与制作的意义,扁平化个人网站EJB Singleton Bean是EJB 3.1规范引入的#xff0c;通常用于存储缓存的数据。 这意味着#xff0c;我们尝试通过使用Singleton来提高应用程序的性能。 总的来说#xff0c;这很好。 特别是在并行调用不多的情况下。 但是#xff0c;如果我们忽略默认锁#xff0c;并且并行… EJB Singleton Bean是EJB 3.1规范引入的通常用于存储缓存的数据。 这意味着我们尝试通过使用Singleton来提高应用程序的性能。 总的来说这很好。 特别是在并行调用不多的情况下。 但是如果我们忽略默认锁并且并行调用的数量增加它就会改变。 合理的默认值 让我们从一些Java代码开始看看如何合理设置锁。 以下代码片段显示了一个简单的带有计数器和两个方法的EJB Singleton。 method1将计数器的当前值写入日志method2的计数从0到100。 Singleton
Remote(SingletonRemote.class)
public class DefaultLock implements SingletonRemote {Logger logger Logger.getLogger(DefaultLock.class.getName());private int counter 0;Overridepublic void method1() {this.logger.info(method1: counter);}Overridepublic void method2() throws Exception {this.logger.info(start method2);for (int i 0; i 100; i) {counter;logger.info( counter);}this.logger.info(end method2);}
} 如您所见没有定义锁。 如果我们同时调用两个方法您希望在日志文件中看到什么 2014-06-24 21:18:51,948 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 5) method1: 0
2014-06-24 21:18:51,949 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 4) start method2
2014-06-24 21:18:51,949 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 4) 1
2014-06-24 21:18:51,949 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 4) 2
2014-06-24 21:18:51,950 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 4) 3...
2014-06-24 21:18:51,977 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 4) 99
2014-06-24 21:18:51,977 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 4) 100
2014-06-24 21:18:51,978 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 4) end method2
2014-06-24 21:18:51,978 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 6) method1: 100
2014-06-24 21:18:51,981 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 7) method1: 100
2014-06-24 21:18:51,985 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 8) method1: 100
2014-06-24 21:18:51,988 INFO [blog.thoughts.on.java.singleton.lock.DefaultLock] (EJB default - 9) method1: 100 好的这可能有点意外默认是整个Singleton上的容器管理的写锁定。 这是一个很好的默认设置以避免同时修改属性。 但是如果我们要执行只读操作那么这是一个糟糕的默认设置。 在这种情况下方法调用的序列化将导致高负载下较低的可伸缩性和较低的性能。 如何避免呢 这个问题的答案很明显我们需要注意并发管理。 和Java EE中一样有两种方法可以处理它。 我们可以自己做也可以要求容器做。 Bean托管并发 我不想过多地讨论Bean管理的并发性。 这是管理并发访问的最灵活的方法。 容器允许并发访问Singleton的所有方法并且您必须根据需要保护其状态。 这可以通过使用sync和volatile来完成。 但是要小心很多时候这并不像看起来那样容易。 容器管理并发 容器托管并发性更易于使用但不如Bean托管方法灵活。 但是根据我的经验对于一般用例来说已经足够了。 正如我们在日志中看到的那样容器管理的并发性是EJB Singleton的默认值。 容器为整个Singleton设置写锁定并序列化所有方法调用。 我们可以更改此行为并在方法和/或类级别上定义读写锁。 这可以通过使用 javax.ejb.Lockjavax.ejb.LockType注释Singleton类或方法来完成。 LockType枚举提供值WRITE和READ来定义互斥写锁定或读锁定。 以下代码片段显示了如何将method1和method2的Lock设置为LockType.READ 。 Singleton
Remote(SingletonRemote.class)
public class ReadLock implements SingletonRemote {Logger logger Logger.getLogger(ReadLock.class.getName());private int counter 0;OverrideLock(LockType.READ)public void method1() {this.logger.info(method1: counter);}OverrideLock(LockType.READ)public void method2() throws Exception {this.logger.info(start method2);for (int i 0; i 100; i) {counter;logger.info( counter);}this.logger.info(end method2);}
} 如前所述我们可以通过使用LockLockType.READ注释类而不是同时使用这两种方法来实现相同的目的。 好的如果一切都按预期进行则应该并行访问这两种方法。 因此让我们看一下日志文件。 2014-06-24 21:47:13,290 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 10) method1: 0
2014-06-24 21:47:13,291 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) start method2
2014-06-24 21:47:13,291 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 1
2014-06-24 21:47:13,291 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 2
2014-06-24 21:47:13,291 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 3...
2014-06-24 21:47:13,306 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 68
2014-06-24 21:47:13,307 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 69
2014-06-24 21:47:13,308 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 3) method1: 69
2014-06-24 21:47:13,310 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 70
2014-06-24 21:47:13,310 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 71...
2014-06-24 21:47:13,311 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 76
2014-06-24 21:47:13,311 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 77
2014-06-24 21:47:13,312 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 2) method1: 77
2014-06-24 21:47:13,312 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 78
2014-06-24 21:47:13,312 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 79...
2014-06-24 21:47:13,313 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 83
2014-06-24 21:47:13,313 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 84
2014-06-24 21:47:13,314 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 5) method1: 84
2014-06-24 21:47:13,316 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 85
2014-06-24 21:47:13,316 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 86
2014-06-24 21:47:13,317 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 87
2014-06-24 21:47:13,318 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 88
2014-06-24 21:47:13,318 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 6) method1: 89
2014-06-24 21:47:13,318 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 89
2014-06-24 21:47:13,319 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 90...
2014-06-24 21:47:13,321 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 99
2014-06-24 21:47:13,321 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) 100
2014-06-24 21:47:13,321 INFO [blog.thoughts.on.java.singleton.lock.ReadLock] (EJB default - 1) end method2结论 在本文开头我们发现Java EE使用容器管理的写锁作为默认值。 这导致所有方法调用的序列化处理并降低了应用程序的可伸缩性和性能。 在实现EJB Singleton时我们需要牢记这一点。 我们看了两个用于控制并发管理的现有选项Bean管理的并发和容器管理的并发。 我们使用容器托管方法为单例的这两种方法定义了一个读锁。 这不像bean管理的方法那样灵活但是它更容易使用并且在大多数情况下足够了。 我们只需要提供一个注释容器将处理其余的注释。 翻译自: https://www.javacodegeeks.com/2014/06/java-ee-pitfalls-1-ignore-the-default-lock-of-a-singleton.html