tags:

views:

255

answers:

4

Hello,

I created a chat application and seems to work just fine except that it takes up 100% cpu. Can this loop take out 100% Cpu? If yes, then what do i do to overcome it?

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

Thanks in advance :)

Hi Bozho, Phil and Starkey. This is the exception that i get.

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)

And this exception continues endlessly as it is in loop. I would like to add that everything works fine. But this starts if some client is connected to serversocket and i again redeploy my application :d. I know you woulnt't want to do that, but still how should i avoid it? Should i remove the inner try catch? so that once any error comes it is directly thrown out of loop? But this doesn't seem practical. Does it? Since one client may face some problem connecting to the serversocket, does not mean that i should terminate my application only. Now can you all help me?

This is my whole ChatRoom class :-

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

}

This is my ChatServer's cleanupStreams:-

//clean up streams
    public void cleanUpStreams() throws IOException{
        _objServerSocket.close();
        for(ChatRoom objChatRoom : _objChatRooms)
            objChatRoom.cleanUpStreams();
    }

This is my Singleton bean which starts up as soon as application is deployed :-

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

}

Please ask me if anything else too is needed.

This is my ChatClient's releaseStreams :-

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

        _objObjectOutputStream.close();
        _objObjectInputStream.close();
        _clientSocket.close();
    }
A: 

It's difficult to know exactly what is going on without the definitions of initializeConnection() and addNewChatClient().

Starkey
+3  A: 

This will take 100% of CPU:

        while (true) {
            try {

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

            } catch (Exception ex) {
            }
        }

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

That's why first of all handle the exception in that try-catch block. I think you'll easily find the problem after that.

Roman
Hi Roman, i know the error. But i don't know how to avoid it. As i said it happens, when come client is already connected to socket and again redeploy my application.
Ankit Rathod
+1  A: 

In answer to your question yes it can if it never reaches

Thread.sleep(1000);

Because of an exception. Maybe this should be moved to the beginning of the try block or after the catch block so in the case a series of error occurs it doesn't retry immediately.

Though you would also be best off stopping this exception from occuring apart from in exceptional cases anyway.

Martin Smith
+2  A: 

I concurr that exceptions will cause the loop to spin continually with no pause - putting Thread.sleep() at the start of the loop will improve things.

That you are getting a ConcurrentModificationException hints that you are either modifying the collection during iteration over them in cleanupStreams() or some other thread is modifying the collection.

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

This seems a bit suspect, and a potential cause of the concurrent modification. If clients only need read access then change this to

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

If the list of ChatClients can be modified, then you should take steps to ensure modifications are done in a thread-safe manner. This is a deep subject, but for starters, you can use Collections.synchronizedList() to ensure all operations are synchronized. Your iterator will also need to on this list, see the javadoc for that method for details.

mdma