我正在为网站提供通知服务。我希望能够实时接收通知,因此我使用Java AsyncResponse来实现这一点。我遇到了一个问题,在某些情况下,我的ajax调用的后端在调用后20秒内无法运行。为了测试它,我启动了3页,然后尝试添加新通知。如果我等了足够长的时间,没有问题,但如果我不等,不是每个页面都会更新,因为不是每个页面都是轮询。是否存在导致问题的错误,或者我可以采取哪些措施来确定导致问题的原因?谢谢!
Java代码:
@Path("/demo0825/notifications")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class NotificationsResource {
@Singleton
@Startup
public static class Storage{
public static ArrayList<AsyncResponse> arList = new ArrayList<>();
private static final Object lock = new Object();
}
@GET
@Path("/poll")
public void pollNotifications(@Suspended AsyncResponse ar){
Date dateobj = new Date();
synchronized (Storage.lock) {
Storage.arList.add(ar);
}
}
@POST
public final Response addNotification(Notification pData) throws Exception {
try (NotificationDataAccess dataAccess = new NotificationDataAccess()) {
dataAccess.add(pData);
synchronized (Storage.lock) {
for (AsyncResponse ar : Storage.arList) {
ar.resume(pData);
}
Storage.arList.clear();
}
return Response.ok().build();
}
}
Javascript代码:
pollNotifications = function(){
console.log("here");
$.ajax({
url: "/atrt_ent/rest/demo0825/notifications/poll",
contentType: 'application/json',
type: "GET",
success: function(data){
console.log(data);
...
}
},
complete: function(){
console.log("here");
pollNotifications();
}
});
}
pollNotifications();
我正在使用chrome并显示时间戳,以便在调用ajax时第一个console.log("here")
日志,然后我可以看到带有debug语句的java代码中的日期。我在没有锁的情况下也完成了这项工作,并得到了相同的结果。
答案 0 :(得分:0)
对象锁定是static
对象。因此,在pollNotifications
中使用它会影响addNotification
。您只在ArrayList
块内使用 arList synchronized
。
我建议您使用Collections.synchronizedList
而不是ArrayList本身。这应该可以正常工作:public static List<AsyncResponse> arList = Collections.synchronizedList(new ArrayList<AsyncResponse>());
现在,您可以删除synchronized块和锁定对象本身,因为JVM控制对象同步。