首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >线程:对同步的深入理解

线程:对同步的深入理解
EN

Stack Overflow用户
提问于 2013-12-18 21:25:17
回答 1查看 194关注 0票数 1

我只想在同步的同时对内在机制有一个更深入的了解。我准备了3个例子。我有一些问题涉及到每个问题。下面是第一个例子:

代码语言:javascript
运行
复制
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 ),它们都可以同时执行,不是吗?它们引用不同的对象,因此没有任何同步。是对的吗?

第二个例子:

代码语言:javascript
运行
复制
public class SyncExamples 
{

    SyncClass sync1 = new SyncClass();


    public void execute1()
    {       
        sync1.process();
    }


    public void execute2()
    {       
        sync1.process();
    }




    class SyncClass
    {

        public synchronized void process()
        {

        }
    }
}

所以在这个例子中,它们引用的对象是相同的。所以这里有一个互斥物。它们是同步的。但让我们来看看我最感兴趣的例子。

代码语言:javascript
运行
复制
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()的调用有效,因为此方法定义了锁?

一天后我添加了以下示例:

代码语言:javascript
运行
复制
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()无效,因为它是一个不同的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-18 21:33:07

第一个问题:正确

第二种情况:是的,表现得像互斥。

第三个问题:正确

回答编辑

synchronized块使用它的参数对象作为块的锁(或者更好的是互斥对象)。因此,如果两个线程到达同一对象上的关键部分synchronized,则只允许一个线程进入其关键部分,而另一个线程则等待此线程退出关键部分。

synchronized方法只是synchronized块的语法糖,因此

代码语言:javascript
运行
复制
class SyncClass
{
    public synchronized void process()
    {

    }
}

可以写成

代码语言:javascript
运行
复制
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部分中的代码不能并发执行。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20668721

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档