提问者:小点点

同步方法java,它是如何工作的


1.

public class SynchronizedCounter
 {
private int c = 0;`

     public synchronized void increment() 
     {
         c++;
     }

    public synchronized void decrement() 
    {
        c--;
    }

    public synchronized int value() 
    {
        return c;
    }
}

2.

public class MyThread extends Thread
 {
     private int threadId;
     private final static Object obj = new Object();

     public MyThread(int threadId)
     {
         this.threadId = threadId;
     }

     @Override
     public void run()
     {
         synchronized (obj)
         {
             for (int i = 0; i < 1000; i++)
                 System.out.println(this.threadId);
         }
    }
}

我想提出我的推理,并请你指出它是否正确。

Ex 1所有3个方法都是同步的。它们是非静态的,并在该类的给定实例上同步。这意味着,如果我们有一个SynsynizedCounter类的对象c1,那么如果thread1执行,例如,增量方法,那么这个方法以及所有其他同步方法都被其他线程阻塞,其他线程不能同时调用这些方法。

Ex 2这里我们在最后,重要的是,静态obj对象上阻塞run方法的主体。由于是静态的,它是类的一个属性,因此由该类的所有对象共享,静态obj是MyThread所有实例的公共监视器。所以如果thread1调用run方法,它将在obj对象上阻塞它。并且由于obj对象是静态的,这意味着在阻塞它的线程解除阻塞之前,没有其他线程能够调用这个方法。


共1个答案

匿名用户

不完全是。

#1其他线程不能同时调用这些方法

其他线程CAN调用这些方法,但是它们将被阻止进入该方法,直到同步锁被释放,并且哪个线程访问锁是不确定的。

它相当于同步(this){…}

#2这意味着没有其他线程将无法调用此方法

任何线程都可以调用run方法,但只有单个线程可以获取obj的锁并进入同步块。

见:

  • 监视器输入
  • 监控

使用同步强制JVM获取和释放锁,即使没有争用。

您应该在#2中查看用于乐观锁定的包java. util.concurrent.lock,并在java.util.concurrent.原子中查看实现#1的更好方法。