Java 线程安全与同步
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21792030/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Threadsafe vs Synchronized
提问by Nayak
I'm new to java. I'm little bit confused between Threadsafe and synchronized. Thread safe means that a method or class instance can be used by multiple threads at the same time without any problems occurring. Where as Synchronized means only one thread can operate at single time.
我是 Java 新手。我对 Threadsafe 和 synchronized 有点困惑。线程安全意味着一个方法或类实例可以被多个线程同时使用而不会出现任何问题。同步意味着一次只能运行一个线程。
So how they are related to each other?
那么它们之间是如何关联的呢?
回答by fastcodejava
Thread safety is a desired behavior of the program, where the synchronized
block helps you achieve that behavior. ?There are other methods of obtaining Thread safety e.g immutable class/objects. Hope this helps.
线程安全是程序所需的行为,其中synchronized
块可以帮助您实现该行为。?还有其他获得线程安全的方法,例如不可变的类/对象。希望这可以帮助。
回答by killjoy
Nayak, when we declare a method as synchronized, all other calls to it from other threads are locked and can wait indefinitely. Java also provides other means of locking with Lock objects now.
Nayak,当我们将一个方法声明为同步方法时,来自其他线程的所有其他调用都会被锁定并且可以无限期地等待。Java 现在还提供了其他锁定 Lock 对象的方法。
You can also declare an object to be final or volatile to guarantee its availability to other concurrent threads.
您还可以将对象声明为 final 或 volatile 以保证其对其他并发线程的可用性。
ref: http://www.javamex.com/tutorials/threads/thread_safety.shtml
参考:http: //www.javamex.com/tutorials/threads/thread_safety.shtml
回答by Nathan Hughes
The definition of thread safety given in Java Concurrency in Practiceis:
Java Concurrency in Practice 中给出的线程安全的定义是:
A class is thread-safe if it behaves correctly when accessed from multiple threads, regardless of the scheduling or interleaving of the execution of those threads by the runtime environment, and with no additional synchronization or other coordination on the part of the calling code.
如果一个类在从多个线程访问时行为正确,则该类是线程安全的,无论运行时环境对这些线程的执行进行调度或交错,并且调用代码部分没有额外的同步或其他协调。
For example, a java.text.SimpleDateFormat object has internal mutable state that is modified when a method that parses or formats is called. If multiple threads call the methods of the same dateformat object, there is a chance a thread can modify the state needed by the other threads, with the result that the results obtained by some of the threads may be in error. The possibility of having internal state get corrupted causing bad output makes this class not threadsafe.
例如,java.text.SimpleDateFormat 对象具有内部可变状态,当调用解析或格式化的方法时会修改该状态。如果多个线程调用同一个dateformat对象的方法,一个线程就有可能修改其他线程需要的状态,导致某些线程得到的结果可能出错。内部状态被破坏导致输出错误的可能性使得这个类不是线程安全的。
There are multiple ways of handling this problem. You can have every place in your application that needs a SimpleDateFormat object instantiate a new one every time it needs one, you can make a ThreadLocal holding a SimpleDateFormat object so that each thread of your program can access its own copy (so each thread only has to create one), you can use an alternative to SimpleDateFormat that doesn't keep state, or you can do locking using synchronized
so that only one thread at a time can access the dateFormat object.
有多种方法可以处理这个问题。您可以让应用程序中需要 SimpleDateFormat 对象的每个地方在每次需要时实例化一个新对象,您可以创建一个 ThreadLocal 持有 SimpleDateFormat 对象,以便程序的每个线程都可以访问自己的副本(因此每个线程只有要创建一个),您可以使用不保持状态的 SimpleDateFormat 的替代方法,或者您可以使用锁定,synchronized
以便一次只有一个线程可以访问 dateFormat 对象。
Locking is not necessarily the best approach, avoiding shared mutable state is best whenever possible. That's why in Java 8 they introduced a date formatter that doesn't keep mutable state.
锁定不一定是最好的方法,尽可能避免共享可变状态是最好的。这就是为什么在 Java 8 中他们引入了一个不保持可变状态的日期格式化程序。
The synchronized
keyword is one way of restricting access to a method or block of code so that otherwise thread-unsafe data doesn't get corrupted. This keyword protects the method or block by requiring that a thread has to acquire exclusive access to a certain lock (the object instance, if synchronized is on an instance method, or the class instance, if synchronized is on a static method, or the specified lock if using a synchronized block) before it can enter the method or block, while providing memory visibility so that threads don't see stale data.
该synchronized
关键字是限制对方法或代码块的访问的一种方式,这样线程不安全的数据就不会被破坏。该关键字通过要求线程必须获得对某个锁的独占访问来保护方法或块(对象实例,如果同步在实例方法上,或类实例,如果同步在静态方法上,或指定的锁定(如果使用同步块),然后才能进入方法或块,同时提供内存可见性,以便线程不会看到过时的数据。
回答by Aakash Verma
After patiently reading through a lot of answers and not being too technical at the same time, I could say something definite but close to what Nayakhad already replied to fastcodejavaabove, which comes later on in my answer but look
在耐心地阅读了大量答案并且同时不太技术性之后,我可以说一些明确但接近Nayak已经在上面回复fastcodejava 的内容,稍后在我的回答中出现,但请看
synchronization is not even close to brute-forcing thread-safety; it's just making a piece of code (or method) safe and incorruptible for a single authorized thread by preventing it from being used by any other threads.
同步甚至不接近强制线程安全;它只是通过防止任何其他线程使用一段代码(或方法)来使单个授权线程安全且不会损坏。
Thread safety is about how all threads accessing a certain element behave and get their desired results in the same way if they would have been sequential (or even not so), without any form of undesired corruption (sorry for the pleonasm) as in an ideal world.
线程安全是关于访问某个元素的所有线程如何表现并以相同的方式获得他们想要的结果,如果它们本来是顺序的(甚至不是这样),没有任何形式的不希望有的损坏(对不起,pleonasm),就像理想中的那样世界。
One of the ways of achieving proximity to thread-safety would be using classes in java.util.concurrent.atomic.
实现接近线程安全的方法之一是使用java.util.concurrent.atomic 中的类。
Sad, that they don't have finalmethods though!
可悲的是,他们没有最终的方法!
回答by Ravindra babu
Thread safety: A thread safe program protects it's data from memory consistency errors. In a highly multi-threaded program, a thread safe program does not cause any side effects with multiple read/write operations from multiple threads on shared data (objects). Different threads can share and modify object data without consistency errors.
线程安全:线程安全程序保护其数据免受内存一致性错误的影响。在高度多线程的程序中,线程安全的程序不会对共享数据(对象)的多个线程的多个读/写操作产生任何副作用。不同的线程可以共享和修改对象数据而不会出现一致性错误。
synchronized
is one basic method of achieving ThreadSafe code.
synchronized
是实现ThreadSafe代码的一种基本方法。
Refer to below SE questions for more details:
有关更多详细信息,请参阅以下 SE 问题:
What does 'synchronized' mean?
You can achieve thread safety by using advanced concurrency API. This documentation pageprovides good programming constructs to achieve thread safety.
您可以通过使用高级并发 API 来实现线程安全。此文档页面提供了实现线程安全的良好编程结构。
Lock Objectssupport locking idioms that simplify many concurrent applications.
锁定对象支持简化许多并发应用程序的锁定习惯用法。
Concurrent Collectionsmake it easier to manage large collections of data, and can greatly reduce the need for synchronization.
并发集合可以更轻松地管理大型数据集合,并且可以大大减少同步需求。
Atomic Variableshave features that minimize synchronization and help avoid memory consistency errors.
原子变量具有最小化同步并有助于避免内存一致性错误的功能。
ThreadLocalRandom(in JDK 7) provides efficient generation of pseudorandom numbers from multiple threads.
ThreadLocalRandom(在 JDK 7 中)提供了从多个线程高效生成伪随机数的功能。
Refer to java.util.concurrentand java.util.concurrent.atomicpackages too for other programming constructs.
其他编程结构也请参考java.util.concurrent和java.util.concurrent.atomic包。
Related SE question:
相关 SE 问题:
回答by Joel Mata
In practice, performance wise, Thread safe, Synchronised, non-thread safe and non-synchronised classes are ordered as:
在实践中,性能明智、线程安全、同步、非线程安全和非同步类的顺序如下:
Hashtable(slower) < Collections.SynchronizedMap < HashMap(fastest)
回答by mbagat
Synchronized: only one thread can operate at same time. Threadsafe: a method or class instance can be used by multiple threads at the same time without any problems occurring. If you relate this question as, Why synchronized methods are thread safe? than you can get better idea.
同步:只有一个线程可以同时运行。线程安全:一个方法或类实例可以被多个线程同时使用而不会出现任何问题。如果您将这个问题联系为,为什么同步方法是线程安全的?比你能得到更好的主意。
As per the definition this appears to be confusive. But not,if you understand it analytically.
根据定义,这似乎令人困惑。但不是,如果你从分析上理解它。
Synchronized means: sequentially one by one in an order,Not concurrently [Not at the same time]. synchronized method not allows to act another thread on it, While a thread is already working on it.This avoids concurrency. example of synchronization: If you want to buy a movie ticket,and stand in a queue. you will get the ticket only after the person in front of you get the ticket.
同步的意思是:一个接一个地依次,非同时[Not at the same time]。同步方法不允许在它上面操作另一个线程,而一个线程已经在它上面工作。这避免了并发。同步的例子:如果你想买一张电影票,然后排队。只有在你前面的人拿到票后,你才能拿到票。
Thread safe means: method becomes safe to be accessed by multiple threads without any problem at the same time.synchronized keyword is one of the way to achieve 'thread safe'. But Remember:Actually while multiple threads tries to access synchronized method they follow the order so becomes safe to access. Actually, Even they act at the same time, but cannot access the same resource(method/block) at the same time, because of synchronized behavior of the resource.
线程安全意味着:方法变得安全,可以被多个线程同时访问而没有任何问题。synchronized 关键字是实现“线程安全”的方法之一。但请记住:实际上,当多个线程尝试访问同步方法时,它们遵循顺序,因此可以安全访问。实际上,即使它们同时动作,但由于资源的同步行为,不能同时访问相同的资源(方法/块)。
Because If a method becomes synchronized, so this is becomes safe to allow multiple threads to act on it, without any problem. Remember:: multiple threads "not act on it at the same time" hence we call synchronized methods thread safe.
因为如果一个方法变得同步,那么允许多个线程对其进行操作就变得安全了,没有任何问题。请记住:多个线程“不会同时作用于它”,因此我们称同步方法为线程安全的。
Hope this helps to understand.
希望这有助于理解。