Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java android.os.Handler类是否消除了将某些方法声明为已同步的需要?_Java_Android_Multithreading_Handler_Synchronized - Fatal编程技术网

Java android.os.Handler类是否消除了将某些方法声明为已同步的需要?

Java android.os.Handler类是否消除了将某些方法声明为已同步的需要?,java,android,multithreading,handler,synchronized,Java,Android,Multithreading,Handler,Synchronized,在编写一个简单的“时钟”应用程序时,我发现Android要求您使用线程a中的Android.os.Handler,以便使用来自线程B的数据结果更新线程a中的视图对象 我对Java还比较陌生,这是我第一次明确地讨论线程,但我知道如果两个不同的线程想要访问相同的数据,通常会将方法和/或操作声明为同步的。尽管如此,android.os.Handler似乎是一种特定于android的线程间数据同步方式,因此可以避免我刚才链接到的Oracle文档中的详细内容。这是真的吗 如果我发现自己处于这样一种情况,A

在编写一个简单的“时钟”应用程序时,我发现Android要求您使用线程a中的Android.os.Handler,以便使用来自线程B的数据结果更新线程a中的视图对象

我对Java还比较陌生,这是我第一次明确地讨论线程,但我知道如果两个不同的线程想要访问相同的数据,通常会将方法和/或操作声明为同步的。尽管如此,android.os.Handler似乎是一种特定于android的线程间数据同步方式,因此可以避免我刚才链接到的Oracle文档中的详细内容。这是真的吗


如果我发现自己处于这样一种情况,Android操作系统要求我使用Android.OS.Handler将数据从一个线程传递到另一个线程,这是否意味着我不必声明用于派生数据的方法是同步的

如果您有一个共享资源,比如
ArrayList
或者可以同时从两个线程读取的东西,那么您只需要
同步

处理程序本身并不阻止任何并发性,它只是使执行UI线程中需要发生的事情变得更加容易,即使工作线程正在尝试执行这些事情

回答您的问题:如果您使用处理程序,通常意味着您在UI线程中执行某些关键操作。例如,您有一个
ArrayList
,您可以在
onCreate
中初始化它,然后可以在单击处理程序中更新它。现在,如果您使用一个处理程序来修改它,那么对ArrayList的所有访问都将发生在UI线程中,因此不需要进行
同步

但是,一旦从工作线程中访问该ArrayList,就需要同步对它的每次访问。

我的理解:

A只是在两个线程之间传递信息的机制。这不是唯一的机制,但这是谷歌选择用于向活动添加易于使用的方法以执行常见任务的机制

从医生那里

当为您的应用程序创建流程时 应用程序,它的主线程是 专用于运行消息队列 它负责管理 顶级应用程序对象 (活动、广播接收器等) 以及他们创建的任何窗口。你可以 创建自己的线程,然后 与主设备进行通信 应用程序线程通过处理程序。 这是通过打同一个帖子来实现的 或sendMessage方法,但 从你的新线程。给定的 Runnable或消息将被删除 已计划在处理程序的消息中 排队,并在适当时进行处理

主线程正在运行处理程序。处理程序负责运行您的活动和管理应用程序环境。处理程序只是一个消息循环,它从消息队列中分派内容。这就是为什么线程必须运行来创建处理程序的原因。要同步您想在这项工作中完成的其他工作,您必须将请求插入此消息队列,以便主应用程序线程完成您的工作。编写ui时,只要只有一个线程访问对象,它就会正常工作

我想这是为了指出处理程序是执行同步的一种机制。当然,编写的内部代码是为了考虑同步,尽管说“如果多个线程访问它,它需要同步”是一个非常简单的说法。尽管UI是最常见的示例,使用处理程序和循环器只是设计多线程应用程序的一种机制,该应用程序为事件处理提供单线程同步


是否需要同步发送给处理程序的内容在很大程度上取决于发送的内容。如果您谈论的是同步对
post
stuff的调用,那么不,处理程序会处理这个问题。如果您谈论的是发布到处理程序的Runnable内部的代码,那么请意识到处理程序的唯一保证是,您的Runnable将使用创建处理程序的线程执行。您将需要继续提供与其他资源的同步。

“同步”、“等待”和“通知”是低级别的并发结构,在这些结构之上实现了信号量、阻塞队列、屏障和循环器/处理程序等高级并发结构

您在java.util.concurrent(实现高级并发模式/结构)中看到的大部分内容都是在synchronized、wait和notify(如果忽略无锁算法)之上实现的


Looper/Handler机制基本上是生产者-消费者模式的轻量级实现,其中有一个消费者,但有多个生产者。创建它是为了在UI线程和非UI线程之间轻松交换消息。android中的UI线程作为单线程循环(即单个使用者)运行,但可以接收来自多个非UI线程(即通过处理程序的多个生产者)的更新。

关注事件处理程序。。。事实上,时钟本身就是事件调度器,通知相关方诸如“闹钟响了”、“现在是午夜”甚至“时间已经过去,这是我的新时间”之类的事情。当时钟的运行(因此事件的调度)发生在时钟的运行线程中时,这些事件实际上在UI线程中被操作。同样有趣的是,您提到了ArrayList,因为我有一个包含所有事件处理程序对象的ArrayList,时钟的运行线程和UI线程都可以很好地访问它。在这种情况下,我希望能够将多个答案标记为正确答案。这也是一个很好的解释。同时,这也解释了为什么我不需要一个活套