我是java的新手。 我在Threadsafe和synchronized之间有点困惑。 线程安全意味着多个线程可以同时使用方法或类实例,而不会出现任何问题。 同步意味着只有一个线程可以在一次运行。
那么它们是如何相互关联的?
答案 0 :(得分:14)
Java Concurrency in Practice中给出的线程安全定义是:
如果一个类在从多个线程访问时行为正确,则无论运行时环境是否调度或交错执行这些线程,并且调用时没有其他同步或其他协调,该类都是线程安全的代码。
例如,java.text.SimpleDateFormat对象具有内部可变状态,在调用解析或格式化方法时会对其进行修改。如果多个线程调用相同dateformat对象的方法,则线程有可能修改其他线程所需的状态,结果是某些线程获得的结果可能出错。内部状态被破坏导致输出错误的可能性使得这个类不是线程安全的。
有多种方法可以解决此问题。您可以让应用程序中需要SimpleDateFormat对象的每个位置在每次需要时都实例化一个新位置,您可以使ThreadLocal持有一个SimpleDateFormat对象,以便程序的每个线程都可以访问它自己的副本(因此每个线程只有要创建一个,你可以使用不保持状态的SimpleDateFormat替代,或者你可以使用synchronized
进行锁定,这样一次只有一个线程可以访问dateFormat对象。锁定不一定是最好的方法,尽可能避免共享的可变状态。
synchronized
关键字是限制对方法或代码块的访问的一种方式,因此线程不安全的数据不会被破坏。此关键字通过要求线程必须获取对某个锁的独占访问权来保护方法或块(对象实例,如果synchronized是在实例方法上,或者是类实例,如果synchronized是在静态方法上,或者是指定的锁定(如果使用同步块),然后才能进入方法或块,同时提供内存可见性,以便线程不会看到陈旧数据。
答案 1 :(得分:10)
线程安全是程序的理想行为,synchronized
块可帮助您实现该行为。还有其他获取线程安全性的方法,例如不可变类/对象。希望这会有所帮助。
答案 2 :(得分:5)
线程安全性 :线程安全程序保护其数据免受内存一致性错误的影响。在高度多线程的程序中,线程安全程序不会对共享数据(对象)上的多个线程进行多次读/写操作产生任何副作用。不同的线程可以共享和修改对象数据而没有一致性错误
synchronized
是实现ThreadSafe代码的一种基本方法。
有关详细信息,请参阅以下SE问题:
What does 'synchronized' mean?
您可以使用高级并发API来实现线程安全。本文档page提供了良好的编程结构,以实现线程安全。
Lock Objects支持锁定简化许多并发应用程序的习惯用法。
Concurrent Collections可以更轻松地管理大量数据,并且可以大大减少同步需求。
Atomic Variables具有最小化同步并有助于避免内存一致性错误的功能。
ThreadLocalRandom (在JDK 7中)可以从多个线程中高效生成伪随机数。
对于其他编程结构,也请参阅java.util.concurrent和java.util.concurrent.atomic包。
相关的SE问题:
答案 3 :(得分:2)
在耐心地阅读了很多答案并且不是同时具有太多技术性之后,我可以说一些明确的但接近Nayak已经回复到上面fastcodejava的内容,后面会有在我的回答中,但看看
同步甚至不接近强制线程安全;它只是通过防止任何其他线程使用它来使单个授权线程的代码(或方法)安全且不可破坏。
线程安全是关于访问某个元素的所有线程如何表现并以相同的方式获得所需的结果,如果它们是顺序的(或甚至不是),没有任何形式的不期望的损坏(对不起pleonasm)和理想世界一样。
实现与线程安全性接近的方法之一是使用 java.util.concurrent.atomic 中的类。
很遗憾,他们没有最终方法!
答案 4 :(得分:0)
Nayak,当我们将方法声明为synchronized时,从其他线程对其进行的所有其他调用都会被锁定,并且可以无限期地等待。 Java还提供了其他锁定对象的方法。
您还可以将对象声明为final或volatile,以保证其对其他并发线程的可用性。
参考:http://www.javamex.com/tutorials/threads/thread_safety.shtml
答案 5 :(得分:0)
在实践中,性能方面,线程安全,同步,非线程安全和非同步类的排序如下:
Hashtable(slower) < Collections.SynchronizedMap < HashMap(fastest)
答案 6 :(得分:0)
同步:只有一个线程可以同时运行。 Threadsafe:多个线程可以同时使用方法或类实例,而不会出现任何问题。 如果您将此问题与?,为什么同步方法是线程安全的?你可以得到更好的想法。
根据定义,这似乎是混乱的。但不是,如果你通过分析理解它。
同步意味着:按顺序逐个顺序,不同时[不在同一时间]。 synchronized方法不允许在其上执行另一个线程,而线程已经在处理它。这避免了并发性。 同步示例:如果您想购买电影票,并排队等候。只有在你面前的人拿到机票后才能拿到机票。
线程安全意味着:方法变得安全,可以被多个线程同时访问而没有任何问题。同步关键字是实现线程安全的方法之一。但请记住:实际上,当多个线程尝试访问同步方法时,它们会遵循顺序,因此可以安全访问。实际上,即使它们同时起作用,但由于资源的同步行为,它们不能同时访问相同的资源(方法/块)。
因为如果方法变得同步,那么允许多个线程对其进行操作变得安全,没有任何问题。记住::多个线程&#34; 不能同时对其进行操作&#34;因此我们调用同步方法线程安全。
希望这有助于理解。