在Java中,在代码中声明关键部分的惯用方式如下:
private void doSomething() { // thread-safe code synchronized(this) { // thread-unsafe code } // thread-safe code }
几乎所有块都在上同步 this,但这是否有特定原因?还有其他可能性吗?是否有关于同步对象的最佳实践?(例如Object?的私有实例)
this
Object
首先,请注意以下代码段是相同的。
public void foo() { synchronized (this) { // do something thread-safe } }
和:
public synchronized void foo() { // do something thread-safe }
做 完全一样的事情 。除了代码的可读性和样式之外,它们都不是其中之一。
当您同步方法或代码块时,重要的是要知道 为什么 要这样做,要锁定的 对象 到底是 什么,目的 是 什么 。
还要注意,在某些情况下,您可能需要 客户端同步 代码块,而在这些情况下,您要的监视器(即,同步对象)不一定是必须的this,例如本例:
Vector v = getSomeGlobalVector(); synchronized (v) { // some thread-safe operation on the vector }
我建议您了解有关并发编程的更多知识,一旦您确切了解幕后发生的事情,它将为您提供大量帮助。您应该阅读《Java并行编程》,这是一本关于该主题的好书。如果您想快速了解该主题,请查看Java Concurrency @Sun。
几乎所有块都与此同步,但是是否有特定原因呢?还有其他可能性吗?
该声明使整个方法同步。
private synchronized void doSomething() {
该声明使部分代码块而不是整个方法同步。
从oracle文档页面
使这些方法同步有两个效果:
首先,不可能在同一对象上对同步方法的两次调用进行交错。当一个线程正在为对象执行同步方法时,所有其他为同一对象块调用同步方法的线程(挂起执行),直到第一个线程对该对象完成。
还有其他可能性吗?关于要同步的对象,是否有最佳实践?(例如Object的私有实例?)
同步有很多可能性和替代方法。您可以使用高级并发API(自JDK 1.5版本开始提供)使代码线程安全。
Lock objects Executors Concurrent collections Atomic variables ThreadLocalRandom