我应该始终使我的java代码是线程安全的,还是出于性能原因,只在需要时才这样做?

时间:2022-12-22 21:03:48

If I create classes, that are used at the moment only in a single thread, should I make them thread-safe, even if I don't need that at the moment? It could be happen, that I later use this class in multiple threads, and at that time I could get race conditions and may have a hard time to find them if I didn't made the class thread-safe in the first place. Or should I make the class not thread-safe, for better performance? But premature optimization is evil.

如果我创建仅在单个线程中使用的类,我是否应该使它们成为线程安全的,即使我现在不需要它?可能会发生这种情况,我后来在多个线程中使用这个类,那时我可能会遇到竞争条件,如果我没有首先使用类线程安全的话,可能很难找到它们。或者我应该使该类不是线程安全的,以获得更好的性能?但过早的优化是邪恶的。

Differently asked: Should I make my classes thread-safe if needed (if used in multiple threads, otherwise not) or should I optimize this issue then needed (if I see that the synchronization eats up an important part of processing time)?

不同的问题:如果需要,我应该让我的类线程安全(如果在多个线程中使用,否则不是)或者我应该优化这个问题然后需要(如果我看到同步占用了处理时间的一个重要部分)?

If I choose one of the both ways, are there methods to reduce the disadvantages? Or exists a third possibility, that I should use?

如果我选择其中一种方法,是否有减少缺点的方法?或者存在第三种可能性,我应该使用?

EDIT: I give the reason this question came up to my mind. At our company we have written a very simple user-management that writes the data into property-files. I used it in a web-app and after some work on it I got strange errors, that the user-management forgot about properties of users(including name and password) and roles. That was very annoying but not consistently reproducible, so I think it was race condition. Since I synchronized all methods reading and writing from/on disk, the problem disappeared. So I thought, that I probably could have been avoided all the hassle, if we had written the class with synchronization in the first place?

编辑:我说出这个问题出现在我脑海中的原因。在我们公司,我们编写了一个非常简单的用户管理,将数据写入属性文件。我在一个网络应用程序中使用它,经过一些工作后我得到了奇怪的错误,用户管理忘记了用户的属性(包括名称和密码)和角色。这非常令人讨厌但不能始终如一地重现,所以我认为这是竞争条件。由于我同步了所有从磁盘上读取和写入的方法,因此问题就消失了。所以我想,如果我们首先用同步编写了类,那么我可能已经避免了所有的麻烦了?

EDIT 2: As I look over the tips of Pragmatic Programmer, I saw tip #41: Always Design for Concurrency. This doesn't say that all code should be thread-safe, but it says the design should have the concurrency in mind.

编辑2:当我查看实用程序员的提示时,我看到了提示#41:始终为并发设计。这并不是说所有代码都应该是线程安全的,但是它说设计应该考虑到并发性。

13 个解决方案

#1


19  

Start from the data. Decide which data is explicitly shared and protect it. If at all possible, encapsulate the locking with the data. Use pre-existing thread-safe concurrent collections.

从数据开始。确定明确共享哪些数据并保护它。如果可能的话,用数据封装锁定。使用预先存在的线程安全并发集合。

Whenever possible, use immutable objects. Make attributes final, set their values in the constructors. If you need to "change" the data consider returning a new instance. Immutable objects don't need locking.

尽可能使用不可变对象。使属性最终,在构造函数中设置它们的值。如果您需要“更改”数据,请考虑返回新实例。不可变对象不需要锁定。

For objects that are not shared or thread-confined, do not spend time making them thread-safe.

对于非共享或线程限制的对象,不要花时间使它们成为线程安全的。

Document the expectations in the code. The JCIP annotations are the best pre-defined choice available.

记录代码中的期望。 JCIP注释是可用的最佳预定义选择。

#2


26  

I used to try to make everything thread-safe - then I realised that the very meaning of "thread-safe" depends on the usage. You often just can't predict that usage, and the caller will have to take action anyway to use it in a thread-safe way.

我曾经试图让一切都是线程安全的 - 然后我意识到“线程安全”的含义取决于用法。您通常无法预测该用法,并且调用者无论如何都必须采取操作以线程安全的方式使用它。

These days I write almost everything assuming single threading, and put threading knowledge in the select few places where it matters.

这些天我几乎把所有东西写成单线程,并将线程知识放在重要的几个地方。

Having said that, I do also (where appropriate) create immutable types, which are naturally amenable to multi-threading - as well as being easier to reason about in general.

话虽如此,我也(在适当的时候)创建了不可变类型,这些类型自然适用于多线程 - 并且通常更容易推理。

#3


6  

Follow the prinicple of "as simple as possible, but no simpler." Absent a requirement, you should not make them thread-safe. Doing so would be speculative, and likely unnecessary. Thread-safe programming adds much more complexity to your classes, and will likely make them less performant due to synchronization tasks.

遵循“尽可能简单但不简单”的原则。如果没有要求,则不应使其成为线程安全的。这样做会是推测性的,而且可能是不必要的。线程安全编程为您的类增加了更多的复杂性,并且可能会因同步任务而降低性能。

Unless explicitly stated that an object is thread-safe, the expectation is that it is not.

除非明确声明对象是线程安全的,否则期望它不是。

#4


4  

I personally would only design classes that are "thread-safe" when needed - on the principle of optimise only when needed. Sun seem to have gone the same way with the example of single threaded collections classes.

我个人只会在需要时设计“线程安全”的类 - 根据需要优化的原则。对于单线程集合类的例子,Sun似乎已经采用了同样的方式。

However there are some good principles that will help you either way if you decide to change:

但是,如果您决定更改,有一些好的原则可以帮助您:

  1. Most important: THINK BEFORE YOU SYNCHRONIZE. I had a colleague once who used to synchronize stuff "just in case - after all synchronized must be better, right?" This is WRONG, and was a cause of multiple deadlock bugs.
  2. 最重要的是:在你同步之前想一想。曾经有一位曾经曾经同步过东西的同事“为了以防万一 - 毕竟同步一定要更好,对吗?”这是错误的,并且是多个死锁错误的原因。

  3. If your Objects can be immutable, make them immutable. This will not only help with threading, will help them be safely used in sets, as keys for Maps etc
  4. 如果您的对象可以是不可变的,那么使它们不可变。这不仅有助于线程化,还可以帮助他们安全地使用,作为地图等的关键

  5. Keep your Objects as simple as possible. Each one should ideally only do one job. If you ever find you might want to synchronise access to half the members, then you possibly should split the Object in two.
  6. 保持对象尽可能简单。理想情况下,每个人最好只做一份工作。如果您发现可能希望将访问权限同步到一半成员,那么您可能应该将对象拆分为两个。

  7. Learn java.util.concurrent and use it whenever possible. Their code will be better, faster and safer than yours (or mine) in 99% of cases.
  8. 学习java.util.concurrent并尽可能使用它。在99%的情况下,他们的代码将比你的(或我的)更好,更快,更安全。

  9. Read Concurrent Programming in Java, it's great!
  10. 阅读Java中的Concurrent Programming,真是太棒了!

#5


3  

Just as a side remark: Synchronization != Thread-safety. Even so you might not concurrently modify data, but you might read it concurrently. So keep the Java Memory Model in mind where synchronization means making data reliable available in all threads, not only protecting the concurrent modification of it.

正如旁边的一句话:同步!=线程安全。即便如此,您可能无法同时修改数据,但您可能会同时阅读它。因此,请记住Java Memory Model,同步意味着在所有线程中使数据可靠,而不仅仅是保护它的并发修改。

And yes, in my opinion thread-safety has to built in right from the beginning and it depends on the application logic if you need handling of concurrency. Never assume anything and even if your test seems to be fine, race conditions are sleeping dogs.

是的,在我看来,线程安全必须从一开始就内置,如果你需要处理并发,它依赖于应用程序逻辑。永远不要假设任何东西,即使你的测试看起来很好,种族条件也是睡觉的狗。

#6


2  

I found the JCIP annotations very useful to declare which classes are thread-safe. My team annotates our classes as @ThreadSafe, @NotThreadSafe or @Immutable. This is much clearer than having to read Javadoc, and FindBugs helps us find violations of the @Immutable and @GuardedBy contracts too.

我发现JCIP注释对于声明哪些类是线程安全非常有用。我的团队将我们的类注释为@ ThreadSafe,@ NotThreadSafe或@Immutable。这比阅读Javadoc要清楚得多,而FindBugs也帮助我们查找违反@Immutable和@GuardedBy合同的行为。

#7


1  

You should absolutely know which segments of your code will be multi-threaded and which won't.

您应该完全知道代码的哪些部分将是多线程的,哪些部分不是。

Without being able to concentrate the area of multithreadedness into a small, controllable section, you will not succeed. The parts of your app that are multi-threaded need to be gone over carefully, fully analyzed, understood and adapted for a multi-threaded environment.

如果不能将多线程区域集中到一个小的可控区域,您将无法成功。您的应用程序的多线程部分需要仔细检查,完全分析,理解和适应多线程环境。

The rest does not and therefore making it thread-safe would be a waste.

其余的没有,因此使其线程安全将是一种浪费。

For instance, with the swing GUI, Sun just decided that none of it would be multi-threaded.

例如,使用swing GUI,Sun只是决定它们都不是多线程的。

Oh, and if someone uses your classes--it's up to them to ensure that if it's in a threaded section then make it threadsafe.

哦,如果有人使用你的类 - 它们取决于他们确保如果它在一个线程部分然后使它线程安全。

Sun initially came out with threadsafe collections (only). the problem is, threadsafe cannot be made un-threadsafe (for performance purposes). So now they came out with un-threadsafe versions with wrappers to make them threadsafe. For most cases, the wrappers are unnecessary--assume that unless you are creating the threads yourself, that your class does not have to be threadsafe--but DOCUMENT it in the javadocs.

Sun最初推出了线程安全集合(仅限)。问题是,线程安全不能成为非线程安全的(出于性能目的)。所以现在他们推出了带有包装器的非线程安全版本,以使它们成为线程安全的。对于大多数情况,包装器是不必要的 - 假设除非你自己创建线程,你的类不必是线程安全的 - 但是在javadocs中记录它。

#8


1  

Here's my personal approach:

这是我的个人方法:

  • Make objects and data structure immutable wherever you can. That is good practice in general, and is automatically thread safe. Problem solved.
  • 尽可能使对象和数据结构不可变。这是一般的好习惯,并且自动是线程安全的。问题解决了。

  • If you have to make an object mutable then normally don't bother trying to make it thread safe. The reasoning for this is simple: when you have mutable state then locking / control cannot be safely handled by a single class. Even if you synchronize all the methods, this doesn't guarantee thread safety. And if you add synchronisation to an object that only ever gets used in a single-threaded context, then you've just added unnecessary overhead. So you might as well leave it up to the caller / user to implement whatever locking system is necessary.
  • 如果你必须使一个对象变得可变,那么通常不要试图使它的线程安全。这样做的原因很简单:当你有可变状态时,单个类不能安全地处理锁定/控制。即使您同步所有方法,这也不能保证线程安全。如果您将同步添加到仅在单线程上下文中使用的对象,那么您只是添加了不必要的开销。因此,您可以将其留给调用者/用户来实现任何必要的锁定系统。

  • If you provide a higher level public API then implement whatever locking is required to make your API thread safe. For higher level functionality the overhead of thread safety is pretty trivial, and your users will definitely thank you. An API with complicated concurrency semantics that the users need to work around is not a good API!
  • 如果您提供更高级别的公共API,则实现使API线程安全所需的任何锁定。对于更高级别的功能,线程安全的开销非常小,您的用户肯定会感谢您。用户需要解决的具有复杂并发语义的API不是一个好的API!

This approach has served me well over time: you may need to make the occasional exception but on average it's a very good place to start!

这种方法随着时间的推移对我很有用:你可能需要偶尔例外,但平均来说这是一个非常好的起点!

#9


0  

If you want to follow what Sun did in the Java API, you can take a look at the collection classes. Many common collection classes are not thread-safe, but have thread-safe counterparts. According to Jon Skeet (see comments), many of the Java classes were originally thread-safe, but they were not benefiting developers, so some classes now have two versions - one being thread-safe and the other not thread-safe.

如果您想要遵循Sun在Java API中所做的操作,您可以查看集合类。许多常见的集合类不是线程安全的,但具有线程安全的对应类。根据Jon Skeet(参见评论),许多Java类最初是线程安全的,但它们并没有使开发人员受益,因此一些类现在有两个版本 - 一个是线程安全的,另一个不是线程安全的。

My advice is to not make the code thread-safe until you have to, as there is some overhead involved with thread-safety. I guess this falls into the same category as optimization - don't do it before you have to.

我的建议是不要让代码在线程安全,因为线程安全涉及一些开销。我想这与优化属于同一类别 - 在你不得不这样做之前不要这样做。

#10


0  

Design separately the classes to use from multiple threads and document other ones to be used from only single thread.

分别设计要从多个线程使用的类,并记录仅从单个线程使用的其他类。

Single threaded ones are much easier to work with.

单线程更容易使用。

Separating the multithreaded logic helps to make the synchronization correct.

分离多线程逻辑有助于使同步正确。

#11


0  

"Always" is a very dangerous word in software development... choices like this are "always" situational.

“永远”在软件开发中是一个非常危险的词......像这样的选择是“永远”的情境。

#12


0  

To avoid race conditions, lock on only one object - read descriptions of race conditions tediously and you will discover that cross-locks ( race condition is a misnomer - race comes to halt there ) are always a consequence of two + threads trying to lock on two + objects.

为了避免竞争条件,只锁定一个对象 - 繁琐地阅读竞争条件的描述,你会发现交叉锁定(竞争条件是用词不当 - 竞争停止在那里)总是两个+线程试图锁定的结果两个+对象。

Make all methods synchronized and do testing - for any real world app that actually has to deal with the issues sync is a small cost. What they don't tell you is that the whole thing does lockout on 16 bit pointer tables ... at that point you are uh,...

使所有方法同步并进行测试 - 对于任何真正需要处理问题同步的真实应用程序,只需很少的成本。他们没有告诉你的是整个事情确实锁定了16位指针表......那时你就是呃,......

Just keep your burger flippin resume' current.

只要保持你的汉堡flippin恢复'当前。

#13


0  

If I create classes, that are used at the moment only in a single thread, should I make them thread-safe

如果我创建仅在单个线程中使用的类,我应该使它们是线程安全的

It is not necessary for a class used by a thread to by itself thread-safe for the program as a whole to be thread-safe. You can safely share objects of non "thread safe" classes between threads if they are protected by appropriate synchronization. So, there is no need to make a class itself thread-safe until that becomes apparent.

线程使用的类本身不需要线程安全的程序作为整体是线程安全的。如果受到适当同步的保护,您可以安全地在线程之间共享非“线程安全”类的对象。因此,除非变得明显,否则不需要使类本身具有线程安全性。

However, multi-threading is fundamental (architectural) choice in a program. It is not really something to add as an after thought. So you should know right from the start which classes need to be thread safe.

但是,多线程是程序中的基本(架构)选择。事实并非如此。所以你应该从一开始就知道哪些类需要线程安全。

#1


19  

Start from the data. Decide which data is explicitly shared and protect it. If at all possible, encapsulate the locking with the data. Use pre-existing thread-safe concurrent collections.

从数据开始。确定明确共享哪些数据并保护它。如果可能的话,用数据封装锁定。使用预先存在的线程安全并发集合。

Whenever possible, use immutable objects. Make attributes final, set their values in the constructors. If you need to "change" the data consider returning a new instance. Immutable objects don't need locking.

尽可能使用不可变对象。使属性最终,在构造函数中设置它们的值。如果您需要“更改”数据,请考虑返回新实例。不可变对象不需要锁定。

For objects that are not shared or thread-confined, do not spend time making them thread-safe.

对于非共享或线程限制的对象,不要花时间使它们成为线程安全的。

Document the expectations in the code. The JCIP annotations are the best pre-defined choice available.

记录代码中的期望。 JCIP注释是可用的最佳预定义选择。

#2


26  

I used to try to make everything thread-safe - then I realised that the very meaning of "thread-safe" depends on the usage. You often just can't predict that usage, and the caller will have to take action anyway to use it in a thread-safe way.

我曾经试图让一切都是线程安全的 - 然后我意识到“线程安全”的含义取决于用法。您通常无法预测该用法,并且调用者无论如何都必须采取操作以线程安全的方式使用它。

These days I write almost everything assuming single threading, and put threading knowledge in the select few places where it matters.

这些天我几乎把所有东西写成单线程,并将线程知识放在重要的几个地方。

Having said that, I do also (where appropriate) create immutable types, which are naturally amenable to multi-threading - as well as being easier to reason about in general.

话虽如此,我也(在适当的时候)创建了不可变类型,这些类型自然适用于多线程 - 并且通常更容易推理。

#3


6  

Follow the prinicple of "as simple as possible, but no simpler." Absent a requirement, you should not make them thread-safe. Doing so would be speculative, and likely unnecessary. Thread-safe programming adds much more complexity to your classes, and will likely make them less performant due to synchronization tasks.

遵循“尽可能简单但不简单”的原则。如果没有要求,则不应使其成为线程安全的。这样做会是推测性的,而且可能是不必要的。线程安全编程为您的类增加了更多的复杂性,并且可能会因同步任务而降低性能。

Unless explicitly stated that an object is thread-safe, the expectation is that it is not.

除非明确声明对象是线程安全的,否则期望它不是。

#4


4  

I personally would only design classes that are "thread-safe" when needed - on the principle of optimise only when needed. Sun seem to have gone the same way with the example of single threaded collections classes.

我个人只会在需要时设计“线程安全”的类 - 根据需要优化的原则。对于单线程集合类的例子,Sun似乎已经采用了同样的方式。

However there are some good principles that will help you either way if you decide to change:

但是,如果您决定更改,有一些好的原则可以帮助您:

  1. Most important: THINK BEFORE YOU SYNCHRONIZE. I had a colleague once who used to synchronize stuff "just in case - after all synchronized must be better, right?" This is WRONG, and was a cause of multiple deadlock bugs.
  2. 最重要的是:在你同步之前想一想。曾经有一位曾经曾经同步过东西的同事“为了以防万一 - 毕竟同步一定要更好,对吗?”这是错误的,并且是多个死锁错误的原因。

  3. If your Objects can be immutable, make them immutable. This will not only help with threading, will help them be safely used in sets, as keys for Maps etc
  4. 如果您的对象可以是不可变的,那么使它们不可变。这不仅有助于线程化,还可以帮助他们安全地使用,作为地图等的关键

  5. Keep your Objects as simple as possible. Each one should ideally only do one job. If you ever find you might want to synchronise access to half the members, then you possibly should split the Object in two.
  6. 保持对象尽可能简单。理想情况下,每个人最好只做一份工作。如果您发现可能希望将访问权限同步到一半成员,那么您可能应该将对象拆分为两个。

  7. Learn java.util.concurrent and use it whenever possible. Their code will be better, faster and safer than yours (or mine) in 99% of cases.
  8. 学习java.util.concurrent并尽可能使用它。在99%的情况下,他们的代码将比你的(或我的)更好,更快,更安全。

  9. Read Concurrent Programming in Java, it's great!
  10. 阅读Java中的Concurrent Programming,真是太棒了!

#5


3  

Just as a side remark: Synchronization != Thread-safety. Even so you might not concurrently modify data, but you might read it concurrently. So keep the Java Memory Model in mind where synchronization means making data reliable available in all threads, not only protecting the concurrent modification of it.

正如旁边的一句话:同步!=线程安全。即便如此,您可能无法同时修改数据,但您可能会同时阅读它。因此,请记住Java Memory Model,同步意味着在所有线程中使数据可靠,而不仅仅是保护它的并发修改。

And yes, in my opinion thread-safety has to built in right from the beginning and it depends on the application logic if you need handling of concurrency. Never assume anything and even if your test seems to be fine, race conditions are sleeping dogs.

是的,在我看来,线程安全必须从一开始就内置,如果你需要处理并发,它依赖于应用程序逻辑。永远不要假设任何东西,即使你的测试看起来很好,种族条件也是睡觉的狗。

#6


2  

I found the JCIP annotations very useful to declare which classes are thread-safe. My team annotates our classes as @ThreadSafe, @NotThreadSafe or @Immutable. This is much clearer than having to read Javadoc, and FindBugs helps us find violations of the @Immutable and @GuardedBy contracts too.

我发现JCIP注释对于声明哪些类是线程安全非常有用。我的团队将我们的类注释为@ ThreadSafe,@ NotThreadSafe或@Immutable。这比阅读Javadoc要清楚得多,而FindBugs也帮助我们查找违反@Immutable和@GuardedBy合同的行为。

#7


1  

You should absolutely know which segments of your code will be multi-threaded and which won't.

您应该完全知道代码的哪些部分将是多线程的,哪些部分不是。

Without being able to concentrate the area of multithreadedness into a small, controllable section, you will not succeed. The parts of your app that are multi-threaded need to be gone over carefully, fully analyzed, understood and adapted for a multi-threaded environment.

如果不能将多线程区域集中到一个小的可控区域,您将无法成功。您的应用程序的多线程部分需要仔细检查,完全分析,理解和适应多线程环境。

The rest does not and therefore making it thread-safe would be a waste.

其余的没有,因此使其线程安全将是一种浪费。

For instance, with the swing GUI, Sun just decided that none of it would be multi-threaded.

例如,使用swing GUI,Sun只是决定它们都不是多线程的。

Oh, and if someone uses your classes--it's up to them to ensure that if it's in a threaded section then make it threadsafe.

哦,如果有人使用你的类 - 它们取决于他们确保如果它在一个线程部分然后使它线程安全。

Sun initially came out with threadsafe collections (only). the problem is, threadsafe cannot be made un-threadsafe (for performance purposes). So now they came out with un-threadsafe versions with wrappers to make them threadsafe. For most cases, the wrappers are unnecessary--assume that unless you are creating the threads yourself, that your class does not have to be threadsafe--but DOCUMENT it in the javadocs.

Sun最初推出了线程安全集合(仅限)。问题是,线程安全不能成为非线程安全的(出于性能目的)。所以现在他们推出了带有包装器的非线程安全版本,以使它们成为线程安全的。对于大多数情况,包装器是不必要的 - 假设除非你自己创建线程,你的类不必是线程安全的 - 但是在javadocs中记录它。

#8


1  

Here's my personal approach:

这是我的个人方法:

  • Make objects and data structure immutable wherever you can. That is good practice in general, and is automatically thread safe. Problem solved.
  • 尽可能使对象和数据结构不可变。这是一般的好习惯,并且自动是线程安全的。问题解决了。

  • If you have to make an object mutable then normally don't bother trying to make it thread safe. The reasoning for this is simple: when you have mutable state then locking / control cannot be safely handled by a single class. Even if you synchronize all the methods, this doesn't guarantee thread safety. And if you add synchronisation to an object that only ever gets used in a single-threaded context, then you've just added unnecessary overhead. So you might as well leave it up to the caller / user to implement whatever locking system is necessary.
  • 如果你必须使一个对象变得可变,那么通常不要试图使它的线程安全。这样做的原因很简单:当你有可变状态时,单个类不能安全地处理锁定/控制。即使您同步所有方法,这也不能保证线程安全。如果您将同步添加到仅在单线程上下文中使用的对象,那么您只是添加了不必要的开销。因此,您可以将其留给调用者/用户来实现任何必要的锁定系统。

  • If you provide a higher level public API then implement whatever locking is required to make your API thread safe. For higher level functionality the overhead of thread safety is pretty trivial, and your users will definitely thank you. An API with complicated concurrency semantics that the users need to work around is not a good API!
  • 如果您提供更高级别的公共API,则实现使API线程安全所需的任何锁定。对于更高级别的功能,线程安全的开销非常小,您的用户肯定会感谢您。用户需要解决的具有复杂并发语义的API不是一个好的API!

This approach has served me well over time: you may need to make the occasional exception but on average it's a very good place to start!

这种方法随着时间的推移对我很有用:你可能需要偶尔例外,但平均来说这是一个非常好的起点!

#9


0  

If you want to follow what Sun did in the Java API, you can take a look at the collection classes. Many common collection classes are not thread-safe, but have thread-safe counterparts. According to Jon Skeet (see comments), many of the Java classes were originally thread-safe, but they were not benefiting developers, so some classes now have two versions - one being thread-safe and the other not thread-safe.

如果您想要遵循Sun在Java API中所做的操作,您可以查看集合类。许多常见的集合类不是线程安全的,但具有线程安全的对应类。根据Jon Skeet(参见评论),许多Java类最初是线程安全的,但它们并没有使开发人员受益,因此一些类现在有两个版本 - 一个是线程安全的,另一个不是线程安全的。

My advice is to not make the code thread-safe until you have to, as there is some overhead involved with thread-safety. I guess this falls into the same category as optimization - don't do it before you have to.

我的建议是不要让代码在线程安全,因为线程安全涉及一些开销。我想这与优化属于同一类别 - 在你不得不这样做之前不要这样做。

#10


0  

Design separately the classes to use from multiple threads and document other ones to be used from only single thread.

分别设计要从多个线程使用的类,并记录仅从单个线程使用的其他类。

Single threaded ones are much easier to work with.

单线程更容易使用。

Separating the multithreaded logic helps to make the synchronization correct.

分离多线程逻辑有助于使同步正确。

#11


0  

"Always" is a very dangerous word in software development... choices like this are "always" situational.

“永远”在软件开发中是一个非常危险的词......像这样的选择是“永远”的情境。

#12


0  

To avoid race conditions, lock on only one object - read descriptions of race conditions tediously and you will discover that cross-locks ( race condition is a misnomer - race comes to halt there ) are always a consequence of two + threads trying to lock on two + objects.

为了避免竞争条件,只锁定一个对象 - 繁琐地阅读竞争条件的描述,你会发现交叉锁定(竞争条件是用词不当 - 竞争停止在那里)总是两个+线程试图锁定的结果两个+对象。

Make all methods synchronized and do testing - for any real world app that actually has to deal with the issues sync is a small cost. What they don't tell you is that the whole thing does lockout on 16 bit pointer tables ... at that point you are uh,...

使所有方法同步并进行测试 - 对于任何真正需要处理问题同步的真实应用程序,只需很少的成本。他们没有告诉你的是整个事情确实锁定了16位指针表......那时你就是呃,......

Just keep your burger flippin resume' current.

只要保持你的汉堡flippin恢复'当前。

#13


0  

If I create classes, that are used at the moment only in a single thread, should I make them thread-safe

如果我创建仅在单个线程中使用的类,我应该使它们是线程安全的

It is not necessary for a class used by a thread to by itself thread-safe for the program as a whole to be thread-safe. You can safely share objects of non "thread safe" classes between threads if they are protected by appropriate synchronization. So, there is no need to make a class itself thread-safe until that becomes apparent.

线程使用的类本身不需要线程安全的程序作为整体是线程安全的。如果受到适当同步的保护,您可以安全地在线程之间共享非“线程安全”类的对象。因此,除非变得明显,否则不需要使类本身具有线程安全性。

However, multi-threading is fundamental (architectural) choice in a program. It is not really something to add as an after thought. So you should know right from the start which classes need to be thread safe.

但是,多线程是程序中的基本(架构)选择。事实并非如此。所以你应该从一开始就知道哪些类需要线程安全。