Java中方法、对象、类的同步

Posted

技术标签:

【中文标题】Java中方法、对象、类的同步【英文标题】:Synchronization of methods, objects, class in Java 【发布时间】:2014-03-29 20:59:02 【问题描述】:

我需要澄清一下synchronizationmulti-threaded environment 中的使用。我在下面有一个小例子Class。但我实际上发现很难对以下内容如何工作进行测试;我想要测试用例的原因是为了了解synchronization 如何处理这些不同的场景


如果thread 调用SharedResource.staticMethod,它将获得class.lock,这是否意味着SharedResourceinstance,比如x,将不得不等到它得到lock 执行x.staticMethod

this 中的synchronization 将在block 中获取该代码部分或整个object 的锁定。即另一个thread可以在同一个object上调用同一个method;但执行不属于synchronization block的其余代码

如果上述观点属实,则启用dummy objectlock 不会提供任何额外的好处。对吗?

所以synchronziations有不同的级别。 Class 级别、Object 级别、method 级别和block level。所以这意味着这些个人级别的locks 应该存在吗? 如果我在Object 上获得了锁,另一个Thread 不能在same object 上调用任何methods,但是如果我在method 上获得了锁,另一个thread 可以在不同的@ 上获得锁987654359@。这是正确的吗?

关于如何创建作用于同一对象和同一方法的两个线程的一些提示将很有帮助(我知道我需要扩展Thread 类或实现Runnable 接口)。但不知道如何让两个线程在同一个对象上调用同一个方法。

class SharedResource 
     public Integer x =0;
     public static Integer y=0;
     Object dummy = new Object();
     public Integer z=0;

     public synchronized static void staticMethod()
         System.out.println("static Method is called");
         y++; 
     

     public synchronized void incrementX()
         System.out.println("instance method; incrementX");
         x++;
     

     public void incrementXBlock()
         synchronized(this)
             x++;
         
         System.out.println("instance method; incrementXBlock");
     

     public void incrementZ()
         synchronized (dummy) 
             z++;
          
         System.out.println("synchronized on dummy; incrementZ method ");
     


public class ThreadSynchronization extends Thread 


我已经阅读了这些帖子,但如果我理解清楚,我并不肯定。

Java synchronized method lock on object, or method?, Does java monitor include instance variables?

【问题讨论】:

还有关于java同步的好文章javarevisited.blogspot.com/2011/04/… 只有一种同步类型,即在对象上。同步对象的使用位置和方式决定了它是哪个对象。 Java 以监视器的方式运行。因此,当您同步对象 objectA 和 objectB 时,会获得不同的锁。 @SotiriosDelimanolis: docs.oracle.com/javase/tutorial/essential/concurrency/… 提到“当线程调用同步方法时,它会自动获取该方法对象的内在锁,并在方法返回时释放它。”这是否意味着存在方法锁? @eagertoLearn 它说that method's object。在对象上调用实例方法。该线程将获取该对象的监视器。没有方法锁之类的东西。 【参考方案1】:
class SharedResource 
  public synchronized static void staticMethod()
    System.out.println("static Method is called");
    y++; 
  
  public synchronized void incrementX()
     System.out.println("instance method; incrementX");
     x++;
  

做同样的事情

class SharedResource 
  public static void staticMethod()
    synchronized(SharedResource.class) 
      System.out.println("static Method is called");
      y++;
    
  
  public void incrementX()
    synchronized(this) 
      System.out.println("instance method; incrementX");
      x++;
    
  

简单地说,进入同步块的线程将在该块的持续时间内获取指定对象上的锁。这意味着最多一个线程可以为特定的锁对象执行synchronized 代码块。由于Class 实例和该类的特定实例是不同的对象,synchronized static 方法和synchronized 实例方法不会相互阻塞。但是“方法级”和“块级”没有区别;重要的一点是选择哪个对象进行同步。

【讨论】:

感谢您的解释。我想测试其中的一些,如何创建两个作用于相同对象并调用相同方法的线程?我问题的最后一点 参见docs.oracle.com/javase/tutorial/essential/concurrency/…“定义和启动线程”部分或“SimpleThreads 示例”

以上是关于Java中方法、对象、类的同步的主要内容,如果未能解决你的问题,请参考以下文章

Java中哪些情况需要同步方法访问?

java关键字有哪些?

java线程同步-synchronized

Java面试

Java多线程---同步与锁

Java线程同步操作