Java 线程中的Android无限循环

Java 线程中的Android无限循环,java,android,multithreading,loops,Java,Android,Multithreading,Loops,我有我的UI和其他线程,其中有循环: while(true){ } 我正在检查系统中字符串值的更改,当更改时,我通过预打开的套接字将消息发送到服务器。问题是,当应用循环时,我的应用程序冻结,CPU负载非常高(约90%)。我知道,无限循环不能在线程中完成,但你们知道如何复制这种行为,而不是使用无限循环吗 Thx 主代码(onCreate方法): mProgressDialog = ProgressDialog.show(main.this, "loading","loading", t

我有我的UI和其他线程,其中有循环:

while(true){

}
我正在检查系统中字符串值的更改,当更改时,我通过预打开的套接字将消息发送到服务器。问题是,当应用循环时,我的应用程序冻结,CPU负载非常高(约90%)。我知道,无限循环不能在线程中完成,但你们知道如何复制这种行为,而不是使用无限循环吗

Thx

主代码(onCreate方法):

    mProgressDialog = ProgressDialog.show(main.this, "loading","loading", true);
    c=new Client(this.getApplicationContext(), "192.168.0.121", 3333);
    c.start();

    CLIENT_MESSAGE="login user2 user2";
    synchronized(c){
        c.notify();
    }
    Client.zHandler.setEmptyMessage(119);


    mHandler = new Handler()
    {
        public void handleMessage(android.os.Message msg)
        {
            super.handleMessage(msg);

            switch (msg.what)
            {
                case 11:
                    Log.d("Logged in", "login");
                    mProgressDialog.dismiss();
                    break;
                case 12:    
                    Log.d("Logged out", "logout and end");
                    mProgressDialog.dismiss();
                    finish();
                    break;

                        }
                 }
          };

  @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    switch (keyCode) {

    case KeyEvent.KEYCODE_BACK:
        CLIENT_MESSAGE="logout";
        synchronized (c) {
            c.notify();
        }
                    Client.zHandler.setEmptyMessage(129)
        break;
    default:

    }
    return true;
}
线程代码(Client.java):


如果您的循环确实在一个单独的线程中运行,那么问题在于它占用CPU

与其轮询检查
字符串
值的更改,不如编写一个setter(如果您可以控制相关代码)从另一个线程触发服务器更新(例如,使用
等待
/
通知
协议)

即使你必须投票,你真的需要在CPU速度下投票吗?也许一秒钟一次就可以了?那会让你在剩下的时间里睡觉

至少,每次通过循环调用
Thread.yield()

编辑根据您对帖子的评论,您应该在后台线程中等待:

while (!isInterrupted()) {
    synchronized (this) {
        wait();
    } catch (InterruptedException e) {
        break; // interrupting the thread ends it
    }
    // read string and send it to the server
}
在后台线程中:

while (!isInterrupted()) {
    synchronized (this) {
        wait();
    } catch (InterruptedException e) {
        break; // interrupting the thread ends it
    }
    // read string and send it to the server
}
在事件处理程序中:

public void onSomethingHappened(...) {
    // update the string
    synchronized (mThread) {
        mThread.notify();
    }
}
除非读取和更新在同一对象上同步,否则字符串应标记为volatile。

synchronized(blah){
    blah.wait();
}
是执行同步的旧方法。查看java.util.concurrent包中的一些类

例如,在您的活动中,您可以实现/添加TextWatcher,并使用您可以使用的方法

blockingQueue.put(theChangedText) //preferably you would do the put via an access method.
然后在你的线程中,你大概会有:

obj = blockingQueue.take()
sendToServer(obj)

我认为在你的情况下,无限循环是合适的。问题是,你正在一个非常紧密的循环中进行检查——比你需要检查的次数多得多。您需要以多快的速度响应值更改?也许添加一个暂停500毫秒的
Thread.sleep()
就足够快了,这样系统的其余部分就可以运行了。一些上下文会很好。等待更改的字符串值是多少?也许有一个没有繁忙循环的解决方案?我正在等待消息,用户输入。当在UI中输入消息时,我通过处理程序工作线程通知,在那个里执行向服务器发送消息happens@Waypoint消息是否输入到一个
EditText
?@Raghav-不,UI线程生成它,它只是一个普通字符串谢谢,我正在尝试在我的代码中使用它,我正在将线程作为对象的一部分启动-Client c=new Client();c、 start();当我使用notify方法时,它对我说要锁定对象c,怎么做?@Waypoint-Ah。我的错误。您需要将对
notify()
的调用包装在
synchronized
块中。我更新了代码以显示我的意思。(在您的代码中,您可能会在
c
而不是
mThread
上进行同步)感谢您的努力。我已经在我的代码中实现了它。但我还是没有成功。当我第一次通知字符串更改时,服务器不会发生任何事情,当我第二次发送消息时,第一次发送并解析,第二次不发送send@Waypoint-听起来像是逻辑中的顺序错误。您需要发布您的代码以获得整理帮助。@Waypoint-您发布的代码有点混乱。但乍一看,您似乎在向客户端发送消息之前先调用了
notify
。这会在客户端收到新消息之前将其唤醒,并可能解释您描述的行为。