同步function如何在java中运行?

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

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

在引擎盖下,它在字节代码级别使用两个操作码monitorentermonitorexit ,它在JVM全局级别获取/释放对象引用的锁定。 我强烈建议您阅读Java虚拟机如何执行线程同步 。

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

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)。

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

 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的访问,直到线程1完成其请求。

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

Java中的同步并不比C语言简单得多。 语法上它更容易,因为您需要为互斥锁做的只是将方法声明为synchronized或use

 synchronized(someObject) { someCode(); } 

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

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

简短的答案:

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

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

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

阅读有关并发的Java教程。 如果你想继续学习,请在实践中阅读Java并发 。

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

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

我在上面看到了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; } }