同步function如何在java中运行?
自从我开始用Java编程以来,我一直在想这个(大约一年或两年)。 在C中,我们必须知道正确避免线程之间死锁的不同方法,因此在同步方法之间有更多的选择。
那Java呢? 当我们同步时,它如何避免将线程置于死锁状态? 它在内部如何运作? 死锁是否被避免,因为我们在更高级别上比在C(或C ++)中同步? 有关java中的死锁和同步的任何文档?
在引擎盖下,它在字节代码级别使用两个操作码monitorenter
和monitorexit
,它在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库。
但是关于僵局的陷阱与任何语言基本相同。
简短的答案:
-
synchronized
方法和lock
块使用监视器 ,该监视器在方法或块的持续时间内锁定锁定对象的信号量 。 -
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; } }
- Selenium偶尔会出现UnreachableBrowserException
- Bouncy castle提供未知的HashAlgorithm
- 如何在轴上禁用SSLv2套接字协议
- 为什么(长)9223372036854665200d给我9223372036854665216?
- writeAll(ResultSet res,Boolean b)opencsv方法在数据周围添加双引号
- 找到给出集合的最长的单词
- 是否可以注册在Java applet完全加载时触发的javascript事件?
- action类不使用liferay中的struts2将对象传递给jsp类
- 通过Java中的for-each循环检测第一次迭代