2010-05-15 2 views
0

Я создал приложение для чата и, похоже, отлично работает, за исключением того, что он занимает 100% -ный процессор. Может ли этот цикл вывести 100% Cpu? Если да, то что мне делать, чтобы преодолеть это?Может ли этот цикл получить 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()); 
     } 
    } 

Заранее спасибо :)

Привет Bozho, Фил и Старки. Это исключение, которое я получаю.

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) 

И это исключение продолжается бесконечно, поскольку оно находится в цикле. Я хотел бы добавить, что все работает нормально. Но это начинается, если какой-либо клиент подключен к serverocket, и я снова передислоцирую мое приложение: d. Я знаю, что вы не хотите этого делать, но все же, как я должен избегать этого? Должен ли я удалить внутренний try catch? так что, как только возникнет какая-либо ошибка, он выкинут из цикла напрямую? Но это не кажется практичным. Имеет ли это? Поскольку один клиент может столкнуться с какой-либо проблемой, связанной с сервером serverocket, не означает, что я должен прервать только мое приложение. Теперь вы можете мне помочь?

Это весь мой класс 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(); 
    } 

} 

Это cleanupStreams моей ChatServer в: -

//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(); 
     } 
    } 

} 

Пожалуйста, спросите меня, требуется ли что-то еще.

Это releaseStreams моей ChatClient в: -

public void releaseStreams() throws IOException { 
     multicastData(_objChatUser); 
     this._objChatRoom.getObjChatMembers().remove(this); 

     _objObjectOutputStream.close(); 
     _objObjectInputStream.close(); 
     _clientSocket.close(); 
    } 
+0

Что такое 'initializeConnection' и' addNewChatClient'? Набирает ли он 100% ничего, кроме вращения, или это в одном из этих методов большую часть времени? Я предполагаю, что метод инициализации быстро завершается, если он уже инициализирован? – Phil

+2

распечатать исключение, которое вы отбрасываете – Bozho

+0

Можете ли вы разместить код для 'misc.ChatRoom.cleanUpStreams'? –

ответ

2

Я соглашаюсь с тем, что исключения будут приводить к непрерывному вращению цикла без паузы - установка Thread.sleep() в начале цикла улучшит ситуацию.

Что вы получаете подсказки ConcurrentModificationException, что вы либо изменяете коллекцию во время итерации над ними в cleanupStreams(), либо какой-либо другой поток модифицирует коллекцию.

public ArrayList<ChatClient> getObjChatMembers() { 
     return _objChatMembers; 
    } 

Это кажется немного подозрительным и потенциальной причиной одновременной модификации. Если клиенты нуждаются только доступ для чтения, то изменить это

public List<ChatClient> getObjChatMembers() { 
     return Collecions.unmodifiableList(_objChatMembers); 
    } 

Если список ChatClients может быть изменен, то вы должны принять меры, чтобы обеспечить изменения сделаны в поточно-образом. Это глубокий вопрос, но для начала вы можете использовать Collections.synchronizedList(), чтобы обеспечить синхронизацию всех операций. Ваш итератор также понадобится в этом списке, см. javadoc для этого метода.

0

Это трудно точно знать, что происходит без определений initializeConnection() и addNewChatClient().

3

Это займет 100% ЦП:

 while (true) { 
      try { 

       initializeConnection(); 
       addNewChatClient(); 
       Thread.sleep(1000); 

      } catch (Exception ex) { 
      } 
     } 

     .... 
     initializeConnection() throws Exception { 
      doSmth(); 
      throw new Exception(); 
     } 

Вот почему в первую очередь обработать исключение в этом попробуй поймать блок. Я думаю, что вы легко найдете проблему после этого.

+0

Привет, Роман, я знаю ошибку. Но я не знаю, как этого избежать. Как я уже сказал, это происходит, когда клиент уже подключен к сокету и снова перераспределяет мое приложение. – TCM

1

В ответ на ваш вопрос да, это возможно, если он никогда не достигает

Thread.sleep(1000);

Из-за исключения. Возможно, это должно быть перенесено в начало блока try или после блока catch, поэтому в случае возникновения серии ошибок он не будет немедленно повторять попытку.

Хотя вам также будет лучше прекратить это исключение, если не считать исключительных случаев.

Смежные вопросы