同步功能如何在java中运行?

时间:2011-07-05 14:31:19

标签: java synchronization deadlock

自从我开始使用Java编程以来,我一直在想这个问题(大约一年或两年)。在C中,我们必须知道正确避免线程之间死锁的不同方法,因此在同步方法之间有更多的选择。

那么Java呢?当我们同步时,它如何避免将线程置于死锁状态?它在内部如何运作?死锁是否被避免,因为我们在更高级别上比在C(或C ++)中同步?有关java中死锁和同步的任何文档吗?

7 个答案:

答案 0 :(得分:14)

在幕后,它在字节代码级别使用两个操作码monitorentermonitorexit,它在JVM全局级别上获取/释放对象引用的锁定。我强烈建议您阅读How the Java virtual machine performs thread synchronization

答案 1 :(得分:5)

我们遇到的多线程代码的主要问题是共享数据,我同意,concurency parallizing进程的目的并且“经常”发生在parallalized处理期间线程需要访问以进行读/写共享数据

java synchronized关键字允许以下内容:

它告诉JVM锁定对象的监视器或同步代码的一部分,这使它可以独占访问该部分代码或对象。

以下是Singleton的一个例子:

public class Singleton {
    private Singleton INSTANCE;

    private Singleton() {
    }

    public Singleton getInstance() {
        if (null == INSTANCE) {
            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }
}

这个Singleton不是线程安全的,如果一个线程试图获取一个实例,而另一个也试图做同样的事情(竞争条件),那么在此之前线程第一个完成第二个实例的创建已经可以访问getInstance()方法并创建了自己的Singleton实例,这意味着在T时刻我们应该有两个Singleton实例(当时称为multiton)。

要解决此问题,我们必须同步单例的创建行为,这可以通过synchronized本身上if语句上方的关键字INSTANCE来完成:

public class Singleton {
    private Singleton INSTANCE;

    private Singleton() {
    }

    public Singleton getInstance() {
        synchronized (Singleton.class) {
            if (null == INSTANCE) {
                synchronized(Singleton.class) {
                   Singleton inst = new Singleton();
                   INSTANCE = inst;   
                }
            }
        }
        return INSTANCE;
    }
}

结果是当第一个线程询问Singleton实例并且在创建期间,JVM将锁定INSTANCE的监视器,拒绝任何对INSTANCE的访问,直到第一个线程完成其请求为止。

有不同的方法可以实现这一点,之前引用的书是一个很好的学习来源,javadoc也是。

答案 2 :(得分:1)

在Java中同步并不比在C中容易得多。语法它更容易,因为你需要为互斥锁做的只是将方法声明为synchronized或者使用

synchronized(someObject)
{
   someCode();
}

在C / C ++中,您必须使用特定于操作系统的函数来使用互斥锁,否则您必须使用Boost库。

但是关于死锁的陷阱与任何语言基本相同。

答案 3 :(得分:1)

简答:

  1. synchronized方法和lock块使用监视器,在方法持续时间内锁定锁定对象的信号量或阻止。

  2. Java语言本身并不能防止死锁。这取决于你作为程序员,以确保以正确的顺序锁定/解锁对象以防止争用。

答案 4 :(得分:0)

您还必须处理Java中的死锁。获得死锁的最简单方法是让一个线程在A上同步运行一个块,然后在B上同步另一个块,而另一个线程执行在B上同步的块,然后在A上同步一个块。

阅读the Java tutorial about concurrency.如果您想继续学习,请阅读Java concurrency in practice

答案 5 :(得分:0)

你试过google (Java Deadlock)吗?第一个结果是:http://download.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

在那里你可以看到,synchronized仍然会出现死锁,因为同步并不是为了防止这些死锁。

答案 6 :(得分:0)

我在上面看到了Singleton的一些问题。我认为这个课永远不会被创造出来。请考虑以下代码。

public class Singleton {
     private static Singleton INSTANCE;
     private Singleton() {     }
     public static Singleton getInstance() {
         synchronized (Singleton.class) {
             if (null == INSTANCE) {
                 synchronized(Singleton.class) {
                    Singleton inst = new Singleton();
                    INSTANCE = inst;
                    }
             }
         }
         return INSTANCE;
     }
 }