由于线程执行发生在池中,并且不能保证以任何特定顺序排队,那么为什么要在没有同步和锁保护的情况下创建线程?为了保护附加到对象状态的数据(我理解为使用线程的主要目的),锁定似乎是唯一的选择。如果你不同步,最终你会遇到竞争条件和“损坏”的数据。因此,如果您对保护该数据不感兴趣,那么为什么要使用线程?
答案 0 :(得分:10)
如果没有共享的可变数据,则不需要同步或锁定。
答案 1 :(得分:9)
代表团,就像一个例子。考虑一个获取连接请求的Web服务器。它可以将特定请求委托给工作线程。主线程可以将所需的所有数据传递给工作线程,只要该数据是不可变的,并且不必担心并发数据访问。
(就此而言,主线程和工作线程都可以将所有不可变数据发送到他们想要的彼此,它只需要某种类型的消息队列,因此队列可能需要同步而不是数据本身。但是你不需要消息队列来获取数据到工作线程,只需在线程启动之前构造数据,并且只要数据在那时是不可变的,您就不需要任何同步或锁定或任何并发管理排序,而不是运行线程的能力。)
答案 2 :(得分:6)
同步和锁定可保护共享状态免受冲突的并发更新的影响。如果没有要保护的共享状态,则可以在不锁定和同步的情况下运行多个线程。这可能是Web服务器中具有多个独立工作线程来处理传入请求的情况。避免同步和锁定的另一种方法是让线程仅在不可变共享状态下运行:如果线程无法更改另一个线程正在运行的任何数据,则并发非同步访问就可以了。
或者您可能正在使用基于Actor的系统来处理并发。参与者只通过消息传递进行通信,没有共享状态让他们担心。所以在这里你可以让很多线程运行很多没有锁的Actors。 Erlang uses this approach,并且有Scala Actors library允许您在JVM上以这种方式编程。此外还有Actors-based libraries for Java。
答案 3 :(得分:4)
为了保护附加的数据 对象的状态(我的理解 成为使用的主要目的 线程),锁定似乎是 唯一的选择。 ... 因此,如果 你对保护不感兴趣 那个数据,然后为什么要使用线程 所有?
您问题的突出位置是不正确的,因为它是您对线程“怀疑”的根本原因,所以需要明确解决。
实际上,使用线程的主要目的是允许任务尽可能并行进行。在多处理器上,并行性(所有条件都相同)会加速计算。但是,还有其他好处也适用于单处理器。最明显的一点是,线程允许应用程序在等待某些IO操作完成时继续工作。
线程实际上并没有以任何有意义的方式保护对象状态。您对线程的保护来自:
您可以独立于线程执行所有这些操作。
答案 4 :(得分:3)
java.util.concurrent.atomic提供了一些可以无锁且线程安全的方式执行的最小操作。如果您可以完全围绕这些类和操作安排并发性,那么您的性能可以大大提高(因为您可以避免与锁定相关的所有开销)。当然,处理这样一个可以简化的问题是很不寻常的(通常需要一些锁定),但是,如果你确实发现自己处于这种情况,那么,那就是你要问的用例! - )
答案 5 :(得分:2)
对共享数据还有其他类型的保护。也许你有原子部分,监视器,软件事务内存或无锁数据结构。所有这些想法都支持并行执行而无需显式锁定您可以使用Google中的任何一个术语来学习有趣的内容。如果您的主要兴趣是Java,请查看Tim Harris的工作。
答案 6 :(得分:1)
线程允许多个并行工作单元同时进行。同步只是为了保护分片资源免受不安全访问,如果不需要你不使用它。
当访问某些资源(例如IO)时,线程上的处理会延迟,并且可能需要让CPU处理其他工作单元,而其他工作单元则会延迟。
在另一个答案的例子中,听取服务请求可能是一个独立于响应请求的工作单元,因为后者是由于资源争用导致的阻塞 - 比如访问磁盘或IO。