当我们使用synchronized关键字时,会被锁定什么?

时间:2014-08-10 20:08:47

标签: java multithreading synchronized

在阅读有关线程中的并发问题并通过synchronized关键字处理它时,我想到的问题是,当我们使用术语lock时,它用于包含{的对象{1}}方法(或线程的工作)。但是为什么我们不能将术语run用于仅包含lock关键字的方法,因为此关键字表示一旦线程进入该方法,那么这个线程只能在方法完成后被JVM调度程序干扰?

我正在从第一个java开始学习,并且那里写着“对象被锁定”的行,并且给出的理由再次以质疑的方式,即“如果我们有两个同步方法会发生什么”。所以我我在这里混淆,如果只锁定方法会发生什么令人惊讶的事情?

如果我提出一个模糊的问题并提前致谢,请原谅我。

3 个答案:

答案 0 :(得分:8)

同步时,线程获取object monitor。由于一次只能有一个线程获取监视器,因此另一个尝试获取它的线程将被阻塞。所以从某种意义上说,除了某段代码之外,没有什么是真正的locked

答案 1 :(得分:3)

使用synchronized关键字隐含等效于使用ReentrantLock,因为javadoc在示例中显示它:

class X {
   private final ReentrantLock lock = new ReentrantLock();
   // ...

   public void m() {
     lock.lock();  // block until condition holds
     try {
       // ... method body
     } finally {
       lock.unlock()
     }
   }
 }

我不知道它是否能回答你的问题,也许我应该让juste做出评论。

答案 2 :(得分:1)

解决您的问题:如果我们有两种同步方法会发生什么?
请考虑以下代码段: -

public class Worker {

private Object lock1 = new Object();
private Object lock2 = new Object();

public void step1() {
    synchronized (lock1) {          
        //do something
    }
}

public void step2() {
    synchronized (lock2) {          
        //do something
    }
}

public void process() {
        step1();
        step2();        
}

public void main() {
    long start = System.currentTimeMillis();
    Thread t1 = new Thread(new Runnable() {

        public void run() {
            process();

        }
    });
    t1.start();
    Thread t2 = new Thread(new Runnable() {

        public void run() {
            process();

        }
    });
    t2.start();

        t1.join();
        t2.join();

    long end = System.currentTimeMillis();
    System.out.println("time taken " + (end - start));

}

}

在这段代码中,我们使用lock1和lock2作为对象锁,但是如果我们使用这个关键字而不是这些锁(lock1和lock2)会发生什么?

  • 不使用关键字所花费的时间(使用lock1,如上所述的lock2)= T
  • 在两个已同步的块中使用关键字所花费的时间= 2T,

由于在两个同步块中使用相同的对象锁定,因此产生了这种时间差。如果thread-1将访问step1方法,则step2方法将被阻塞为thread-2。 如果方法具有独立性,则应使用不同的锁。