JAVA:synchronized关键字阻塞了代码块的哪一部分?并解释这个僵局

标签 java multithreading oracle deadlock

我有个问题:
1.同步方法的代码的哪一部分,即同步块(synchronized block)?
例如:

public class example{

  public synchronized void f1(){
    //some code....
     f2();
    }
    public synchronized void f2()
    {
      //some code...
    }
}
public void main(String[[] args)
{
   Thread t1 = new Thread(new Runnable()
   {public void run(){f1();)},
          t2 = new Thread(new Runnable()
   {public void run(){f2();};
   t1.start();
   t2.start();

}

所以在 t1 启动后,t2 无法启动 - 因为它正在等待 t1。但是当t1开始做f2时,是否意味着t2可以进入f1?

如果可以的话,请解释一下这个死锁示例。我没明白。来源:http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s"
                + "  has bowed to me!%n", 
                this.name, bower.getName());
            bower.bowBack(this);
        }
        public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s"
                + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    public static void main(String[] args) {
        final Friend alphonse = new Friend("Alphonse");
        final Friend gaston = new Friend("Gaston");
        new Thread(new Runnable() {
            public void run() { alphonse.bow(gaston); }}).start();
        new Thread(new Runnable() {
            public void run() { gaston.bow(alphonse); }}).start();
    }
}

最佳答案

Java 中的同步方法会锁定整个方法,重要的是,它会锁定正在调用该方法的对象的实例。这意味着同一对象中的两个同步方法共享相同的锁,因此不能由不同线程并发执行。

例如在下面的类中

public class myClass
{
  synchronized void method1()
  {

  }

  synchronized void method2()
  {

  }
}

method1()method2() 永远不能在同一个对象上同时调用,因为代码相当等效于:

public class myClass
{
  void method1()
  {
    synchronized(this)
    {
      // ...
    }
  }

  void method2()
  {
    synchronized(this)
    {
      // ...
    }
  }
}

如果您希望两种方法在不同的锁上独立同步,那么您可以执行如下操作:

public class myClass
{
  private final Object method1Lock = new Object();
  private final Object method2Lock = new Object();

  void method1()
  {
    synchronized(method1Lock)
    {
      // ...
    }
  }

  void method2()
  {
    synchronized(method2Lock)
    {
      // ...
    }
  }
}

关于JAVA:synchronized关键字阻塞了代码块的哪一部分?并解释这个僵局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25272994/

相关文章:

java - 带绝对目录的 Runtime.exec()

c# - 崩溃后从同一位置启动线程

oracle - 将数据批量插入 Oracle 数据库的最佳方法

oracle - 启动服务时出错。找不到OracleMTSRecoveryService

java - 为什么我不能访问这个其他类的方法?

java - 访问包含 postfix 的服务器并使用它从 spring boot 应用程序发送邮件

multithreading - Java:对从异步任务检索的结果进行排序

java - 为什么 BlockingQueue.take() 不释放线程?

sql - 具有像 where 0=0 这样的条件的确切含义是什么?

java - Android 应用程序 Activity 中的广告横幅实现