Android - 为什么第二个线程会暂停执行第一个线程?

时间:2011-12-15 16:59:14

标签: android multithreading

我有一个在循环中运行2个线程的应用。第一个是以1s间隔更新图形,第二个是以60s间隔更新另一个图形。第二项任务是花费很长时间,因为它在互联网上查询了一些可能并不总是可用的服务器,即使它最多需要5-7秒才能执行。

发生的事情是,当我启动第二个线程时,它将暂停第一个线程的执行,这不是我想要的,我希望它们同时运行。在Youtube视频中,您可以看到应用运行的结果。 http://youtu.be/l7K5zSWzlxI “thread_updater1s”正在运行绿色图形,大型读数和角落中的计时器,因此您可以清楚地看到它停止了11秒。

1)首先为什么会发生这种情况?如何解决?

2)我知道我可能根本没有正确启动线程。我很难理解如何使用Java中的间隔循环来运行某些东西,并且我的代码在一个图形/步骤中运行良好。现在,当我在不同的线程中有2个循环时,我不知道它们为什么不同时执行。

以下是代码:

public class LoopExampleActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.main);
    thread_updater1s.start();
    thread_updater2.start();
}// end of onCreate

final Runnable r1s = new Runnable() {
    public void run() {
        do_1s_updates(); // those are very quick http calls to the local API server 
    }                    // to get data nessessary for some plot.
                        // They have 1s timeout as well but rarely timeout
};

final Runnable r2 = new Runnable() {
    public void run() {
        do_large_updates(); //This makes 7 long call over the Internet to the slow https
                            //server once every 60s. Has 10s timeout and sometimes takes as much as
                            //7s to execute
        }
};

Thread thread_updater1s = new Thread() {
    @Override
    public void run() {
        try {
            while (true) {
                handler.post(r1s);
                sleep(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

Thread thread_updater2 = new Thread() {
    @Override
    public void run() {
        try {
            while (true) {
                handler2.post(r2);
                sleep(60000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

}

PS。请原谅和提供信息我到目前为止只编写Java 15天,绝对没有先前的经验或教训。

2 个答案:

答案 0 :(得分:0)

handler.post将runnable推送到主(UI)线程的消息队列,以便在主线程上执行。

所以你正在做的是每个睡眠间隔,你正在向主线程发送一条消息来运行该函数。显然,主线程不能同时运行两个东西,所以这就是为什么一个runnable会延迟下一个。

您可能希望在单独的线程中执行runnable的工作 - 为什么要开始使用处理程序?如果您直接拨打do_1s_updatesdo_large_updates而不是通过处理程序&可运行?

答案 1 :(得分:0)

您需要在线程中创建http请求(而不是发布的runnables)。然后,当您下载数据时,您将使用该数据创建一个runnable,该数据将更新图形并发布可由UI线程执行的runnable。这是一个例子:

public class LoopExampleActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.main);
    thread_updater1s.start();
    thread_updater2.start();
}// end of onCreate

Thread thread_updater1s = new Thread() {
    @Override
    public void run() {
        try {
            while (true) {
                final Object data = getDataFromServer1();
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        updateGraph1(data);
                    }
                );
                sleep(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

Thread thread_updater2 = new Thread() {
    @Override
    public void run() {
        try {
            while (true) {
                final Object data = getDataFromServer2();
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        updateGraph2(data);
                    }
                );
                sleep(60000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

显然,通过代表您下载数据的相应类更改最终的Object数据。