我创建了一个聊天应用程序,似乎工作正常,但它占用了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();
}
答案 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()的定义,很难确切地知道发生了什么。