我只想在同步的同时对内在机制有一个更深入的了解。我准备了3个例子。我有一些问题涉及到每个问题。下面是第一个例子:
public class SyncExamples
{
SyncClass sync1, sync2;
public void execute1()
{
sync1 = new SyncClass();
sync1.process();
}
public void execute2()
{
sync2 = new SyncClass();
sync2.process();
}
class SyncClass
{
public synchronized void process()
{
}
}
}
SyncClass的方法进程()是同步的。但是由于在类SyncExamples 中创建了两个不同的对象( of SyncClass ),它们都可以同时执行,不是吗?它们引用不同的对象,因此没有任何同步。是对的吗?
第二个例子:
public class SyncExamples
{
SyncClass sync1 = new SyncClass();
public void execute1()
{
sync1.process();
}
public void execute2()
{
sync1.process();
}
class SyncClass
{
public synchronized void process()
{
}
}
}
所以在这个例子中,它们引用的对象是相同的。所以这里有一个互斥物。它们是同步的。但让我们来看看我最感兴趣的例子。
public class SyncExamples
{
SyncClass sync1 = new SyncClass();
ReadWriteLock lock = new ReentrantReadWriteLock();
public void execute1()
{
lock.writeLock().lock();
sync1.process();
lock.writeLock().unlock();
}
public void execute2()
{
execute1();
}
public void execute3()
{
sync1.process();
}
public void execute4()
{
execute1();
}
class SyncClass
{
public void process()
{
}
}
}
execute2()启动execute1()。execute1()锁定sync1.process()。因此,execute4()必须等待,直到sync1.process()被execute1()解锁。但是execute3()呢?它不引用execute1(),而是直接调用sync1.process()而不使用任何锁。因此,execute1()设置的锁对execute3()无效吗?是那么回事吗?该锁仅对引用execute1()的调用有效,因为此方法定义了锁?
一天后我添加了以下示例:
public class SyncExamples
{
List list = new ArrayList();
public void processList1()
{
synchronized(list)
{
}
}
public void processList2()
{
synchronized(list)
{
}
}
public void execute3()
{
processList1();
}
public void execute4()
{
processList2();
}
}
我想澄清最后一个例子。现在我有了一个想要同步的列表。方法processList1()同步列表.方法processList2()也会这样做。但它们能同时执行吗?同步是全局锁定列表(我指的是所有来自其他方法的其他访问),还是仅与特定方法结合使用?在本例中,我仍然不明白execute3()和execute4()是否可以同时执行,因为它们引用了不同的方法。同步阻止对其块的第二次访问。但是有几种方法想要访问列表,它们使用自己的同步块。因此,如果processList1()锁定了列表,那么这个列表是否锁定为processList2()?或者这个锁对processList2()无效,因为它是一个不同的方法?
发布于 2013-12-18 13:33:07
第一个问题:正确
第二种情况:是的,表现得像互斥。
第三个问题:正确
回答编辑
synchronized
块使用它的参数对象作为块的锁(或者更好的是互斥对象)。因此,如果两个线程到达同一对象上的关键部分synchronized
,则只允许一个线程进入其关键部分,而另一个线程则等待此线程退出关键部分。
synchronized
方法只是synchronized
块的语法糖,因此
class SyncClass
{
public synchronized void process()
{
}
}
可以写成
class SyncClass
{
public void process()
{
synchronized(this)
{
// whole body of process() inside this block
}
}
}
所以,回答你的问题
synchronized
将全局锁定list
(或任何其他用作其参数的对象),而不只是针对特定的方法。您可以在代码中的任何地方对对象进行同步,并且无论包含的方法/类或调用层次结构如何,同步部分都将以互斥方式运行。processList1()
和processList2()
不会并发执行。一次只能执行一个。(这假设您在synchonized
块之外没有代码。)execute3()
和execute4()可以并发执行,但只能执行到到达synchronized
部分的程度。也就是说,对processList1()
和processList2()
的调用以及这些调用之前的任何代码-- execute3/4()
方法可以并发执行,但是synchronized
部分中的代码不能并发执行。https://stackoverflow.com/questions/20668721
复制相似问题