简体   繁体   English

Java:最好一次或多次锁定?

[英]Java: Better to get lock once or multiple times?

I realize this is a somewhat general question, but bear with me. 我意识到这是一个有点笼统的问题,但请耐心等待。 Suppose that I have to insert a bunch of items into a data structure. 假设我必须将一堆项插入数据结构中。

  • I can either insert them in one at a time, or in one giant batch. 我可以一次一个地插入它们,也可以一个巨大的批次插入它们。
  • The insert operation must take a lock on my data structure. 插入操作必须锁定我的数据结构。
  • The insertion happens from one thread. 插入发生在一个线程中。
  • I don't have any information about contention for the lock from other parts of the system. 我没有任何关于从系统其他部分争用锁的信息。

Do you think it would be better to insert in batches or one-by-one or it doesn't matter (...where "better" minimizes insertion time and lock hold time)? 你认为最好是分批插入或逐个插入或者无关紧要(......“更好”最小化插入时间和锁定保持时间)?

If only one thread has access to your data structure, then you don't need the lock at all. 如果只有一个线程可以访问您的数据结构,那么您根本不需要锁定。

If multiple threads need access then it's a matter of how large is the "dosage": 如果多个线程需要访问,那么“剂量”有多大:

  • If you lock for each item, then you have very fine grain locking and multiple threads can probably update the list alternatively, allowing all of them to make progress. 如果你锁定每个项目,那么你有非常精细的粒子锁定,多个线程可能会交替更新列表,允许所有这些进展。 However, locking and unlocking many times will start to add up. 但是,多次锁定和解锁将开始加起来。
  • If you lock for the entire batch, then locking has negligible impact, but if the batch is large the other threads will be locked-out until you finish the entire update. 如果锁定整个批次,则锁定的影响可以忽略不计,但如果批次很大,则其他线程将被锁定,直到您完成整个更新。
  • A trade-off would probably be to divide the large batch into a few smaller batches, such that you don't take the lock too many times, yet all the threads are allowed to make some progress by having a chance to take the lock between batch updates. 权衡可能是将大批量分成几个较小的批次,这样你就不会多次锁定,但是所有的线程都可以通过有机会锁定来获得一些进展。批量更新。

using a lock, generally speaking, would be to preserve the atomicy of the operation. 一般来说,使用锁定将保留操作的原子性。 If the whole insertion is done from one thread and you want to ensure that all items are inserted while no other thread in the system can acquire the lock in he middle of the operation - you should choose the giant batch. 如果整个插入是从一个线程完成的,并且您希望确保插入所有项目而系统中没有其他线程可以在操作中间获取锁定 - 您应该选择巨型批处理。 This choice is also performance-wise if looking on the operation itself (only acquire the lock once). 如果查看操作本身(仅获取锁定一次),这种选择也是性能方面的。 On the other hand, if other parts of the system might, while the thread is inserting in giant batch, want to insert or do any other operation that needs to get the lock, they will 'starve'. 另一方面,如果系统的其他部分可能,当线程插入大批量,想要插入或执行任何其他需要锁定的操作时,它们将“饿死”。 So it really a choice of usage by the whole system. 所以它真的是整个系统的使用选择。 If you find out that you are the only thread ever using the lock - you can actually dismiss it... 如果你发现你是唯一一个使用锁的线程 - 你实际上可以解雇它......

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM