Я создал приложение чата и, кажется, работает нормально, за исключением того, что оно занимает 100% процессорного времени. Может ли эта петля убрать 100% ЦП? Если да, то что мне сделать, чтобы преодолеть это?
@Override
public void run(){
try {
_objServerSocket = new ServerSocket(17001, 500);
while (true) {
try {
initializeConnection();
addNewChatClient();
Thread.sleep(1000);
} catch (Exception ex) {
}
}
} catch (IOException ex) {
System.out.println(ex.getCause() + "\n"+ ex.getMessage() + "\n" + ex.getStackTrace());
}
}
Заранее спасибо:)
Привет, Божо, Фил и Старки.
Это исключение, которое я получаю.
SEVERE: java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at misc.ChatRoom.cleanUpStreams(ChatRoom.java:34)
at misc.ChatServer.cleanUpStreams(ChatServer.java:85)
at common.Global.cleanupTasks(Global.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.ejb.containers.interceptors.BeanCallbackInterceptor.intercept(InterceptorManager.java:1006)
at com.sun.ejb.containers.interceptors.CallbackChainImpl.invokeNext(CallbackChainImpl.java:61)
at com.sun.ejb.containers.interceptors.CallbackInvocationContext.proceed(CallbackInvocationContext.java:109)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCallback(SystemInterceptorProxy.java:133)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.destroy(SystemInterceptorProxy.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.ejb.containers.interceptors.CallbackInterceptor.intercept(InterceptorManager.java:961)
at com.sun.ejb.containers.interceptors.CallbackChainImpl.invokeNext(CallbackChainImpl.java:61)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:390)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:373)
at com.sun.ejb.containers.AbstractSingletonContainer$SingletonContextFactory.destroy(AbstractSingletonContainer.java:727)
at com.sun.ejb.containers.AbstractSingletonContainer.doConcreteContainerShutdown(AbstractSingletonContainer.java:638)
at com.sun.ejb.containers.BaseContainer.onShutdown(BaseContainer.java:4111)
at org.glassfish.ejb.startup.SingletonLifeCycleManager.doShutdown(SingletonLifeCycleManager.java:166)
at org.glassfish.ejb.startup.EjbApplication.stop(EjbApplication.java:240)
at org.glassfish.internal.data.EngineRef.stop(EngineRef.java:165)
at org.glassfish.internal.data.ModuleInfo.stop(ModuleInfo.java:268)
at org.glassfish.internal.data.ApplicationInfo.stop(ApplicationInfo.java:251)
at com.sun.enterprise.v3.server.ApplicationLifecycle.unload(ApplicationLifecycle.java:759)
at com.sun.enterprise.v3.server.ApplicationLifecycle.undeploy(ApplicationLifecycle.java:790)
at org.glassfish.deployment.admin.UndeployCommand.execute(UndeployCommand.java:184)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:305)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:320)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1176)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$900(CommandRunnerImpl.java:83)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1235)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1224)
at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:365)
at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:204)
at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:166)
at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:100)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:245)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
at java.lang.Thread.run(Thread.java:619)
SEVERE: java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2249)
at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2542)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2552)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at misc.ChatClient.run(ChatClient.java:71)
SEVERE: java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2249)
at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2542)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2552)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at misc.ChatClient.run(ChatClient.java:71)
SEVERE: java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2249)
at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2542)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2552)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at misc.ChatClient.run(ChatClient.java:71)
SEVERE: java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2249)
at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2542)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2552)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at misc.ChatClient.run(ChatClient.java:71)
SEVERE: java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2249)
at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2542)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2552)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at misc.ChatClient.run(ChatClient.java:71)
SEVERE: java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2249)
at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2542)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2552)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at misc.ChatClient.run(ChatClient.java:71)
SEVERE: java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2249)
at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2542)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2552)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at misc.ChatClient.run(ChatClient.java:71)
SEVERE: java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2249)
at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2542)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2552)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at misc.ChatClient.run(ChatClient.java:71)
SEVERE: java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2249)
at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2542)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2552)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at misc.ChatClient.run(ChatClient.java:71)
SEVERE: java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2249)
at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2542)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2552)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at misc.ChatClient.run(ChatClient.java:71)
И это исключение продолжается бесконечно, поскольку оно находится в цикле. Я хотел бы добавить, что все работает отлично. Но это начинается, если какой-то клиент подключен к serversocket, и я снова переустанавливаю свое приложение: d. Я знаю, что ты не хочешь этого делать, но все же, как мне этого избежать? Должен ли я удалить внутреннюю попытку поймать? так что, как только какая-либо ошибка появляется, она сразу выходит из цикла? Но это не кажется практичным. Является ли? Поскольку один клиент может столкнуться с некоторой проблемой при подключении к сокету сервера, это не значит, что я должен завершить только свое приложение. Теперь вы все можете мне помочь?
Это весь мой класс ChatRoom: -
package misc;
import java.io.IOException;
import java.util.ArrayList;
public class ChatRoom {
private ArrayList<ChatClient> _objChatMembers;
private int roomId = 0;
public ChatRoom(int roomId){
this.roomId = roomId;
this._objChatMembers = new ArrayList<ChatClient>();
System.out.println("Chat ROom created :" + roomId);
}
public ArrayList<ChatClient> getObjChatMembers() {
return _objChatMembers;
}
public int getRoomId() {
return roomId;
}
public void setRoomId(int roomId) {
this.roomId = roomId;
}
public void setObjChatMembers(ArrayList<ChatClient> _objChatMembers) {
this._objChatMembers = _objChatMembers;
}
public void cleanUpStreams() throws IOException{
for(ChatClient objChatClient : _objChatMembers)
objChatClient.releaseStreams();
}
}
Это очистки моего ChatServerStreams: -
//clean up streams
public void cleanUpStreams() throws IOException{
_objServerSocket.close();
for(ChatRoom objChatRoom : _objChatRooms)
objChatRoom.cleanUpStreams();
}
Это мой компонент Singleton, который запускается сразу после развертывания приложения: -
package common;
import entity.UserProfile;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.SessionContext;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.TimerService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import misc.ChatServer;
@Startup
@Singleton
@LocalBean
public class Global{
@EJB
private EmailManagerRemote _objEmailManager;
@EJB
private Utils _objUtils;
@Resource
private SessionContext _objSessionContext;
@PersistenceContext
private EntityManager _objEntityManager;
private TimerService _objTimerService;
private ChatServer _objChatServer;
@PostConstruct
public void init(){
final int TWENTY_FOUR_HOURS = 1000 * 60 * 60 * 24 ;
_objTimerService = _objSessionContext.getTimerService();
_objTimerService.createIntervalTimer(new Date(), TWENTY_FOUR_HOURS , null);
//start chat server
this._objChatServer = new ChatServer();
this._objChatServer.start();
}
@Timeout
public void sendBirthdayGreetingsAndBackupDatabase(){
//send birthday reminders
try{
List<UserProfile> userProfileList = _objEntityManager.createNamedQuery("UserProfile.findByBirthdate").setParameter("birthdate", new Date()).getResultList();
//List<UserProfile> userProfileList = _objEntityManager.createNamedQuery("UserProfile.findAll").getResultList();
for(UserProfile objUserProfile : userProfileList)
_objEmailManager.sendMail(EMAIL_TEMPLATE_CONSTANTS.REGISTRATION,objUserProfile.getUser());
}
catch(Exception ex){
ex.printStackTrace();
}
//backup BMS database
try{
_objUtils.backupBMSDB();
}
catch(Exception ex){
}
}
@PreDestroy
public void cleanupTasks(){
try{
if(_objChatServer != null)
_objChatServer.cleanUpStreams();
}
catch(Exception ex){
ex.printStackTrace();
}
}
}
Пожалуйста, спросите меня, нужно ли что-нибудь еще.
Это релиз моего ChatClientStreams: -
public void releaseStreams() throws IOException {
multicastData(_objChatUser);
this._objChatRoom.getObjChatMembers().remove(this);
_objObjectOutputStream.close();
_objObjectInputStream.close();
_clientSocket.close();
}