同步块和监视器对象

时间:2012-04-05 19:35:34

标签: java

您可以解释一下,如果以下代码中的同步代码将限制对线程的访问。如果是,如果我们使用“this”作为监视器对象而不是“msg”,它是如何不同的。

public void display(String msg)    
{    
    synchronized(msg)    
    {    
        for(int i=1;i<=20;i++)    
          {    
               System.out.println("Name= "+msg);    
          }  
    }   
}

3 个答案:

答案 0 :(得分:13)

只有当两个线程使用完全相同的 msg 对象调用此方法时,您编写的方法才会阻止。

如果您在 this 上进行同步,则只有一个线程能够在给定时间调用该方法。

答案 1 :(得分:6)

synchronized(this)

表示仅锁定此对象实例。如果您有多个线程使用此对象实例并调用此方法,则一次只能有一个线程可以在synchronized块中访问。

synchronized(msg) 

表示锁定基于msg字符串。如果您有多个线程使用此对象实例并调用此方法,则如果msg是不同的实例,则多个线程可以在此synchronized块中访问。谨防Java如何处理字符串相等以避免令人惊讶的效果。

答案 2 :(得分:0)

  

如果以下代码中的同步代码将受到限制   访问线程

是。在同一个String对象[实际上,所有在此String对象上同步的块]上,不能同时调用该块一次。

  

如果我们使用“this”作为监视器对象,它有什么不同   而不是“msg”

synchronized(this)阻止同一对象对所有块的并发访问,在这种情况下,该方法的this对象将无法两次进入同步块。 / p>

例如 [使用类似java的伪代码]:

s1 = s2;
Thread1:
MyObject o = new MyObject();
o.display(s1);
Thread2:
MyObject o = new MyObject();
o.display(s2);

当前方法不允许Thread1和Thread2

同时调用块

然而:

MyObject o = new MyObject();
Thread1:
o.display("s1");
Thread2:
o.display("s2");

不会显示它们之间的阻塞行为 - 监视器被每个“s1”和“s2”捕获而不会互相干扰。