我觉得我非常熟悉Java中的并发性,但我对Java EE及其注释相对较新。
我有一个名为DataHandler
的注释为@Singleton
的类,它为我的应用程序执行一些业务逻辑。此类注入到使用@WebService
注释的Web服务实现类中。当调用其中一个Web服务方法时,DataHandler
会调用解析某些文件的parseFiles()
方法,并将数据存储在DataHandler
内。之后,它会调用DataHandler
内的getter:
@WebService(portName = "portName",
serviceName = "MyService",
endpointInterface = "com.myco.MyPortType",
wsdlLocation = "WEB-INF/wsdl/MyWSDL.wsdl",
targetNamespace = "targetNamespace")
public class MyServiceImpl implements MyPortType {
@EJB
private DataHandler dataHandler;
@Override
public ResponseType doStuff(RequestType request) {
// code
// ....
dataHandler.parseFiles();
// ....
// more code
Map<String, CustomType> map = dataHandler.getCustomTypeMap();
Map<String, CustomType2> map2 = dataHandler.getCustomType2Map();
}
现在我还有消息驱动的bean,它接收一个名为UpdateTopic的主题的数据,然后将其转换为另一种类型并将其存储在DataHandler
内:
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "UpdateTopic")
})
public class UpdateTopicMDB implements MessageListener {
@EJB
DataHandler dataHandler;
@Override
public void onMessage(Message message) {
try {
if (message instanceof ObjectMessage) {
ObjectMessage objMessage = (ObjectMessage) message;
Serializable data = objMessage.getObject();
if (data instanceof UpdateType) {
dataHandler.convertAndStore((UpdateType) data);
}
}
} catch(Exception e) {
// log Exception
}
}
我希望同步parseFiles()
方法,convertAndStore()
方法和两个getter,以便在访问时所有数据都是最新的。
我只是制作了所有四种方法synchronized
来实现这一目标。我的理解是,如果文件正在被解析并且更新进入MDB,则convertAndStore()
方法将被锁定,直到parseFiles()
完成。同样,如果正在转换和存储更新,并且Web服务正在尝试访问两个映射之一,则它将等到convertAndStore()
完成。如果我错了,请纠正我。
尽管如此,我最近才读到@ConcurrencyManagement
和@Lock
注释。而不是同步这四种方法。现在好像我应该用parseFiles()
注释convertAndStore()
和@Lock(LockType.WRITE)
,因为他们正在修改bean的状态和两个使用@Lock(LockType.READ)
的getter。
我应该这样做并完全避免使用synchronized
关键字吗? synchronized
是否有任何用途(可能仅用于同步块?),或者这些注释现在是否替换它?
答案 0 :(得分:0)
编写JavaEE代码时,应避免使用synchronized
和任何其他手动并发实现。不要创建线程和锁。而不是使用JSR 236 (EE concurrency utilities)。