不使用关键字就可以使代码线程安全的可能方法是什么?不使用`synchronized`关键字的线程安全代码?
回答
只有方法本地的变量/引用。或者确保任何实例变量都是不可变的。
不可变的实例变量是否可以接受? – duffymo 2012-04-26 09:48:25
@duffymo编辑 – NimChimpsky 2012-04-26 09:50:16
不错 - 短而重要。 – 2016-11-18 12:16:16
如果没有可变性,一切都是线程安全的,那么可以通过使所有数据不可变,使您的代码成为线程安全的。其次,你可能想看看Java并发API,它提供了读/写锁定的功能,以便在有很多读者和一些作者的情况下执行更好。纯同步关键字也会阻止两位读者。
实际上,很多方面:
- 无需同步在所有如果你没有可变状态。
- 如果可变状态局限于单个线程,则不需要同步。这可以通过使用局部变量或
java.lang.ThreadLocal
来完成。 - 您也可以使用内置同步器。
java.util.concurrent.locks.ReentrantLock
与使用块和方法访问的锁具有相同的功能,并且功能更强大。
我更喜欢(2),但我不确定它是否可能在不使用'synchronized'关键字的情况下实现消息传递。我可以制作一个没有“同步”的生产者 - 消费者队列吗? – 2012-04-26 10:07:17
没关系 - 我可以通过使用java.util.concurrent.Semaphore。 – 2012-04-26 10:10:06
@MartinJames任何类似队列和交换器的并发类都可以在没有同步的情况下使用。 (他们使用Lock来代替)Disrupter支持不锁定或同步的消息传递。 (我有一个库,它也这样做) – 2012-04-26 11:27:08
为什么你需要这样做?
仅使用本地变量/引用不会解决大多数复杂的业务需求。 另外,如果实例变量是不可变的,它们的引用仍然可以被其他线程改变。
其中一种选择是使用类似于SingleThreadModel的东西,但非常不鼓励和弃用。
ü也可以看看并发API通过卡尔
“如果实例变量是不可变的,它们的引用仍然可以改变”不,它们不能 – NimChimpsky 2012-04-26 10:03:37
可以解释。我怎么看它是如果我有一个instanace变量String s =“xyz”,我的thread1可以改变它的引用s =“abc”;和thread2现在会得到s =“abc” – Kshitij 2012-04-26 10:08:15
s是一个引用,它已经改变,它不是不可变的,你需要“最终字符串s” – NimChimpsky 2012-04-26 10:11:51
上面建议保持预见性您必须确保所有访问的可变数据由顺序或处理由并行访问的问题。
最严重的保护使用关键字。除此之外,至少有两层可能性,每一层都有其优点。
锁/信号灯
这些可以是非常有效的。例如,如果您的结构是由多个线程读取的,但只能更新一个,则可能会发现ReadWriteLock
有用。
如果您选择锁定来匹配算法,锁定可以更加高效。
原子能
例如使用AtomicReference
可以经常提供完全无锁的功能。这通常可以提供巨大的好处。
原子背后的推理是让他们失败,但告诉你他们失败的方式,你可以处理它。
例如,如果要更改某个值,则可以读取该值,然后只要它仍旧是旧值就可以写入新值。这被称为“比较和设置”或cas
,通常可以在硬件中实现,因此非常有效。所有你需要的是这样的:
long old = atomic.get();
while (!atomic.cas(old, old+1)) {
// The value changed between my get and the cas. Get it again.
old = atomic.get();
}
但是,请注意,可预测性并不总是要求。
- 1. 关于产品线程安全代码
- 2. 什么是synchronized关键字的使用?
- 3. 学习Java,使用synchronized关键字
- 4. C++多线程 - 线程安全代码
- 5. 在多线程环境中使用DateFormat时使用synchronized关键字
- 6. 关于使用QThreadStorage的线程安全
- 7. 确保代码中的线程安全
- 8. 这是线程安全的代码?
- 9. 此代码是否线程安全?我怎样才能使它线程安全?
- 10. 什么类用于关键字'synchronized'?
- 11. 使“不安全”代码块“安全”
- 12. 关于synchronized关键字如何处理锁定和线程匮乏的问题
- 13. 以下代码是否线程安全
- 14. 这段代码是否线程安全?
- 15. 这段代码线程安全
- 16. 该代码是否线程安全?
- 17. 代码重入与线程安全
- 18. 这段Java代码线程安全吗?
- 19. 使用异步和DataRow的非线程安全代码
- 20. 静态关键字,状态/实例变量和线程安全
- 21. Objective-C __block关键字和线程安全
- 22. 使用不安全代码的原因
- 23. 此代码不是线程安全的,不是吗?
- 24. 单线程在多线程中不使用同步关键字
- 25. 使用线程安全的代码执行停止单例初始化代码
- 26. 使用线程安全或非线程安全的PHP?
- 27. 如何使线程安全,而不是线程安全
- 28. 关于线程安全
- 29. 关于线程安全
- 30. MMGR问题,代码使用和线程安全
为什么关闭?它是一个很好的简洁问题 – NimChimpsky 2012-04-26 09:55:01
@NimChimpsky我也不知道,这个问题似乎对我完全有效。这绝对是可以回答的,答案不是主观的。 – Malcolm 2012-04-26 10:00:59