我只是想在同步时更深入地了解内在机制。我准备了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的方法process()是同步的。但是由于在SyncExamples类中创建了两个不同的对象的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()必须等到execute1()解锁sync1.process()。但是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()同步list ...方法processList2()也是如此。但它们可以同时执行吗? 同步是否全局锁定列表(我的意思是所有来自其他方法的其他访问)或仅与特定方法结合使用?我仍然不明白在这个例子中是否可以同时执行execute3()和execute4(),因为它们引用了不同的方法。已同步可防止对其块进行第二次访问。但是有几种方法想要访问列表并且他们使用自己的同步块。因此,如果processList1()锁定列表,那么此列表是否会为processList2()锁定?或者这个锁对processList2()无效,因为它是一个不同的方法?
答案 0 :(得分:0)
第一个问题:正确的 第二种情况:是的,就像互斥体一样 第三个问题:正确
回答编辑:
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
部分内的代码不能同时执行。< / LI>