这个循环可以取出100%的CPU吗?

时间:2010-05-15 11:22:43

标签: java sockets

我创建了一个聊天应用程序,似乎工作正常,但它占用了100%的CPU。这个循环可以取出100%的Cpu吗?如果是,那么我该怎么做才能克服它?

  @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,Phil和Starkey。 这是我得到的例外。

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。我知道你不想这样做,但我怎么能避免呢?我应该删除内部尝试捕获?所以一旦出现任何错误,它会被直接抛出循环?但这似乎不切实际。可以?由于一个客户端可能在连接到serversocket时遇到一些问题,并不意味着我应该仅终止我的应用程序。现在,你们都可以帮助我吗?

这是我的整个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();
    }

}

这是我的ChatServer的cleanupStreams: -

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

这是我的Singleton bean,它在部署应用程序后立即启动: -

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

}

请问我是否还需要其他任何东西。

这是我的ChatClient的releaseStreams: -

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

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

4 个答案:

答案 0 :(得分:3)

这将占用100%的CPU:

        while (true) {
            try {

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

            } catch (Exception ex) {
            }
        }

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

这就是为什么首先处理try-catch块中的异常的原因。我想你会在那之后轻易找到问题。

答案 1 :(得分:2)

我同意异常将导致循环连续旋转而没有暂停 - 将Thread.sleep()放在循环的开头将改善事情。

您收到的ConcurrentModificationException提示您在cleanupStreams()或其他一些线程正在修改集合时,在迭代过程中修改集合。

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

这似乎有点怀疑,并且是并发修改的潜在原因。如果客户端只需要读取权限,则将其更改为

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

如果可以修改ChatClients列表,那么您应该采取措施确保以线程安全的方式完成修改。这是一个很深的主题,但对于初学者,您可以使用Collections.synchronizedList()来确保所有操作都是同步的。 您的迭代器也需要在此列表中,有关详细信息,请参阅该方法的javadoc

答案 2 :(得分:1)

回答你的问题是的,如果它永远不会达到

Thread.sleep(1000);

由于例外。也许这应该移动到try块的开头或catch块之后,因此在发生一系列错误的情况下它不会立即重试。

虽然你也最好不要在特殊情况下阻止这种例外。

答案 3 :(得分:0)

如果没有initializeConnection()和addNewChatClient()的定义,很难确切地知道发生了什么。