Java 处理程序、可运行线程和线程之间有什么不同?

Java 处理程序、可运行线程和线程之间有什么不同?,java,android,multithreading,android-asynctask,thread-safety,Java,Android,Multithreading,Android Asynctask,Thread Safety,处理程序、可运行和线程之间的区别是什么 当我使用android时,我需要在后台运行一些东西。我使用线程来运行它。通常我会编写一个类来扩展线程并实现run方法 我还看到了一些示例,它们实现了runnable并将runnable传递到线程中 但是我还是很困惑。有人能给我一个清楚的解释吗 如果可以在线程的run方法中编写背景代码,那么Runnable有什么意义 处理程序是如何在线程中使用的,为什么我们需要使用它 Android还有一个东西叫runOnUiThread,我们如何使用它?我知道它是用来更新

处理程序、可运行和线程之间的区别是什么

当我使用android时,我需要在后台运行一些东西。我使用线程来运行它。通常我会编写一个类来扩展线程并实现run方法

我还看到了一些示例,它们实现了runnable并将runnable传递到线程中

但是我还是很困惑。有人能给我一个清楚的解释吗

  • 如果可以在线程的run方法中编写背景代码,那么Runnable有什么意义
  • 处理程序是如何在线程中使用的,为什么我们需要使用它
  • Android还有一个东西叫runOnUiThread,我们如何使用它?我知道它是用来更新用户界面的
  • 如果一个人可以用它来编写背景代码,那么Runnable有什么意义呢 线程的运行方法

    Runnable
    是一个接口,用于创建新的线程类,类似于通过扩展
    java.lang.thread
    类创建的线程类。唯一的区别是,
    Runnable
    接口允许类扩展其他类(如果需要)以覆盖/继承某些类的功能。扩展
    java.lang.Thread
    类将撤销此功能

    此外,Runnable接口表示可以由普通线程、执行器或任何其他方式执行的任务。所以,将任务逻辑分离为可运行而不是线程是一个好的设计决策


    阅读更多信息:

    为什么使用可运行线程?

    • Runnable
      将需要异步运行的代码与代码的运行方式分开。这使您的代码保持灵活性。例如,runnable中的异步代码可以在线程池或专用线程上运行

      线程
      具有您的runnable可能不需要访问的状态。获得超过必要的状态是糟糕的设计

      线程占用大量内存。为每个小动作创建一个新线程需要处理时间来分配和释放内存

    runOnUiThread实际上在做什么?

    • Android将一个
      Runnable
      队列排在UI线程上执行。这很重要,因为您不应该从多个线程更新UI
      runOnUiThread
      使用
      处理程序

      请注意,如果UI线程的队列已满,或者需要执行的项目很长,则排队的
      Runnable
      实际运行可能需要一段时间

    什么是处理程序?

    • 处理程序允许您发布可运行文件以在特定线程上执行。在幕后,rununui线程使用Android的Ui处理程序将您的
      Runnable
      排队,以便您的Runnable可以在Ui线程上安全执行

    处理程序、可运行线程和线程实际上一起工作,我认为您不应该对它们进行比较

    处理者

    允许以安全的方式在两个线程之间发送消息,这意味着发送线程将消息放入目标线程队列,并且该目标队列将在适当的时间处理该消息

    可运行

    这是一个您实现的接口,在实现中,您将要在某个线程上执行的逻辑放入其中。实际上,您也可以在与线程无关的地方使用Runnable。许多JavaAPI实际上使用可运行的,而不仅仅是线程。您可以使用处理程序发布Runnable,也可以将其与执行器一起使用。可运行性很好,因为您可以以匿名实现的形式实现它们

    单线程

    你是说UI线程?大多数用户界面在单线程中实现其工作,所有UI元素:窗口/小部件使用消息进行通信(就像在处理程序中一样)。也就是说,用户按下按钮,这将启动一条消息,其中包含按下按钮的信息,它将被发送到UI线程,并最终发送到您的侦听器


    在Android中,禁止(导致异常)从非UI线程修改UI元素,这是有意义的-如果您从其他线程修改它,这可能发生在UI线程对同一小部件进行某些更改时-导致未定义的行为。

    1。为什么要运行?

    Runnable只是一个接口,您需要实例化一个线程来包含它。然而,线程已经包含生成线程的能力。如果扩展线程,则不能扩展任何其他内容(Java不支持多重继承)。一个类上可以有多个接口,因此可以有Runnable

    此外,当您扩展Thread类时,每个线程都会创建唯一的对象并与之关联。当您实现Runnable时,它将同一个对象共享给多个线程

    2。为什么要使用handler?它是什么?

    处理程序是用Java编写的(内部使用线程),所以您可以使用处理程序执行的所有操作,也可以使用线程实现

    那么为什么要使用Handler呢?原因如下

    • 处理程序允许您发送和处理消息和可运行对象 与线程的MessageQueue关联。简单地说,, handler使您的工作变得轻松

    • Android有两个处理线程的主要规则:

    • 不要阻塞UI线程

    • 不要从UI线程外部访问Android UI工具包
    要按照上述2条规则进行绑定,在android中,我们有3个内置方法,可以处理在不同线程上运行或调用某个活动类的情况

    然后,我们可以使用以下三种方法安排在UI线程上运行UI更新。然后,该活动或视图作为处理程序工作(下面将详细介绍处理程序),并将您的runnable调度到UI线程:

  • Activity.runOnUiThread(可运行)
  • View.post(可运行)
  • View.postDelayed(Runnable,long)/(long=调度时间)
    /**
         * Runs the specified action on the UI thread. If the current thread is the UI
         * thread, then the action is executed immediately. If the current thread is
         * not the UI thread, the action is posted to the event queue of the UI thread.
         *
         * @param action the action to run on the UI thread
         */
        public final void runOnUiThread(Runnable action) {
            if (Thread.currentThread() != mUiThread) {
                mHandler.post(action);
            } else {
                action.run();
            }
        }
    
    public class MainActivity extends AppCompatActivity {    
    private Handler mainHandler=new Handler();
    class ExampleRunnable implements Runnable {
            int seconds;
    
            public ExampleRunnable(int seconds) {
                this.seconds = seconds;
            }
    
            @Override
            public void run() {
                for (int i = 0; i < seconds; i++) {
     mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                            button.setText("50% process completed");
                            }
                        });
    
    class ExampleRunnable implements Runnable {
            int seconds;
    
    
    
     public ExampleRunnable(int seconds) {
            this.seconds = seconds;
        }
    
        @Override
        public void run() {runOnUIThread.post(new Runnable() {
                        @Override
                        public void run() {
                            button.setText(" Runnable");
                        }
                    });
                }
    
    public class MainActivity extends AppCompatActivity {
     private Switch aSwitch;
    @Override
        protected void onCreate(Bundle savedInstanceState) {
     aSwitch=findViewById(R.id.switch1);
    class ExampleRunnable implements Runnable {
                int seconds;
    
    
    
         public ExampleRunnable(int seconds) {
                this.seconds = seconds;
            }
    
            @Override
            public void run() { aSwitch.post(new Runnable() {
                            @Override
                            public void run() {
                                button.setText(" Runnable");
                            }
                        });
                    }
    
    Handler threadHandler=new Handler(Looper.getMainLooper());
    threadHandler.post(new Runnable()
    {
                                @Override
                                public void run() {
                                    button.setText(" Runnable");
                                }
                            });
                        }