是否有创建没有同步和锁的线程的用例?
由于线程执行发生在池中,并且不保证以任何特定顺序排队,那么为什么要在没有同步和锁保护的情况下创建线程呢?为了保护附加到对象状态的数据(我理解这是使用线程的主要目的),锁定似乎是唯一的选择。如果不同步,最终您将遇到竞争条件和“损坏”数据。因此,如果您对保护该数据不感兴趣,那么为什么要使用线程呢?
Since thread execution happens in a pool, and is not guaranteed to queue in any particular order, then why would you ever create threads without the protection of synchronization and locks? In order to protect data attached to an object's state (what I understand to be the primary purpose of using threads), locking appears to be the only choice. Eventually you'll end up with race conditions and "corrupted" data if you don't synchronize. So if you're not interested in protecting that data, then why use threads at all?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
如果没有共享的可变数据,则不需要同步或锁。
If there's no shared mutable data, there's no need for synchronization or locks.
代表团,仅举一例。考虑一个获取连接请求的网络服务器。它可以将特定请求委托给工作线程。主线程可以将它想要的所有数据传递给工作线程,只要该数据是不可变的,并且完全不必担心并发数据访问。
(就此而言,主线程和工作线程都可以将所有不可变数据发送给彼此,它只需要某种消息传递队列,因此队列可能需要同步,但不需要数据本身。但你不需要需要一个消息队列来将数据获取到工作线程,只需在线程启动之前构造数据,并且只要数据在那时是不可变的,您就不需要任何同步或锁或任何类型的并发管理,其他比运行线程的能力。)
Delegation, just as one example. Consider a webserver that gets connect requests. It can delegate to a worker thread a particular request. The main thread can pass all the data it wants to the worker thread, as long as that data is immutable, and not have to worry at all about concurrent data access.
(For that matter, both main thread and worker thread can send all the immutable data to each other they want, it just requires a messaging queue of some sort, so the queue may need synchronization but not the data itself. But you don't need a message queue to get data to a worker thread, just construct the data before the thread starts, and as long as the data is immutable at that point, you don't need any synchronization or locks or concurrency management of any sort, other than the ability to run a thread.)
同步和锁可以保护共享状态免受并发更新冲突的影响。如果没有要保护的共享状态,则可以运行多个线程而无需锁定和同步。在具有多个独立工作线程服务传入请求的 Web 服务器中可能会出现这种情况。避免同步和锁定的另一种方法是让线程仅在不可变共享状态上运行:如果一个线程无法更改另一个线程正在操作的任何数据,则并发非同步访问就可以了。
或者您可能正在使用基于 Actor 的系统来处理并发。 Actor 仅通过消息传递进行通信,无需担心共享状态。所以在这里你可以有很多线程运行很多没有锁的 Actor。 Erlang 使用这种方法,并且有一个 Scala Actors 库,允许您以这种方式进行编程JVM。此外,还有 基于 Actor 的 Java 库。
Synchronization and locks protect shared state from conflicting concurrent updates. If there is no shared state to protect, you can run multiple threads without locking and synchronization. This might be the case in a web server with multiple independent worker threads serving incoming requests. Another way to avoid synchronization and locking is to have your threads only operate on immutable shared state: if a thread can't alter any data that another thread is operating on, concurrent unsynchronized access is fine.
Or you might be using an Actor-based system to handle concurrency. Actors communicate by message passing only, there is no shared state for them to worry about. So here you can have many threads running many Actors without locks. Erlang uses this approach, and there is a Scala Actors library that allows you to program this way on the JVM. In addition there are Actors-based libraries for Java.
您问题中突出显示的部分是不正确的,并且由于它是您对线程“怀疑”的根本原因,因此需要明确解决。
事实上,使用线程的主要目的是在可能的情况下允许任务并行进行。在多处理器上,并行性将(在所有条件相同的情况下)加速您的计算。但单处理器还有其他好处。最明显的一个是线程允许应用程序在等待某些 IO 操作完成的同时执行工作。
线程实际上并不以任何有意义的方式保护对象状态。您归因于线程的保护来自:
您可以独立于线程来完成所有这些操作。
The highlighted bit of your question is incorrect, and since it is the root cause of your "doubts" about threads, it needs to be addressed explicitly.
In fact, the primary purpose for using threads is to allow tasks to proceed in parallel, where possible. On a multiprocessor the parallelism will (all things being equal) speedup your computations. But there are other benefits that apply on a uniprocessor as well. The most obvious one is that threads allow an application to do work while waiting for some IO operation to complete.
Threads don't actually protect object state in any meaningful way. The protection you are attributing to threads comes from:
You can do all of these independently of threading.
java.util.并发.atomic 提供了一些可以以无锁且线程安全的方式执行的最小操作。如果您可以完全围绕此类和操作安排并发性,则可以大大提高性能(因为您避免了与锁定相关的所有开销)。诚然,处理如此简单的问题是不寻常的(更常见的是需要一些锁定),但是,如果您确实发现自己处于这种情况,那么,这正是您所询问的用例!-)
java.util.concurrent.atomic provides for some minimal operations that can be performed in a lock-free and yet thread-safe way. If you can arrange your concurrency entirely around such classes and operations, your performance can be vastly enhanced (as you avoid all the overhead connected with locking). Granted, it's unusual to be working on such a simplifiable problem (more often some locking will be needed), but, if and when you do find yourself in such a situation, well, then, that's exactly the use case you're asking about!-)
还有其他类型的共享数据保护。也许您有原子部分、监视器、软件事务内存或无锁数据结构。所有这些想法都支持并行执行而无需显式锁定。你可以用谷歌搜索这些术语并学习一些有趣的东西。如果您的主要兴趣是 Java,请查找 Tim Harris 的工作。
There are other kinds of protection for shared data. Maybe you have atomic sections, monitors, software transactional memory, or lock-free data structures. All these ideas support parallel execution without explicit locking. You can Google any of these terms and learn something interesting. If your primary interest is Java, look up Tim Harris's work.
线程允许多个并行工作单元同时进行。同步只是为了保护分片资源免受不安全访问,如果不需要,则不要使用它。
当访问某些资源(例如 IO)时,线程上的处理会发生延迟,并且可能需要在其他工作单元延迟时让 CPU 处理其他工作单元。
正如另一个答案中的示例,侦听服务请求很可能是一个独立于响应请求的工作单元,因为后者由于资源争用而被阻止 - 例如访问磁盘或 IO。
Threads allow multiple parallel units of work to progress concurrently. The synchronisation is simply to protect shard resources from unsafe access if not needed you don't use it.
Processing on threads becomes delayed when accessing certain resources such as IO and it may be desirable to keep the CPU processing other units of work while others are delayed.
As in the example in the other answer listening to services requests may well be a unit of work that is kept independent of responding to a request as the latter my block due to resource contention - say access disk or IO.