同步功能在Java中是如何工作的?
自从我开始用Java编程以来,我一直在想这个问题(大约一两年)。在C语言中,我们必须知道不同的方法才能正确避免线程之间的死锁,因此同步方法之间有更多的选择。
那么Java呢?当我们同步时,它如何避免线程陷入死锁状态?它如何在内部工作?是否因为我们在比C(或C++)更高的级别上进行同步而避免了死锁?任何关于Java中的死锁和同步的文档?
自从我开始用Java编程以来,我一直在想这个问题(大约一两年)。在C语言中,我们必须知道不同的方法才能正确避免线程之间的死锁,因此同步方法之间有更多的选择。
那么Java呢?当我们同步时,它如何避免线程陷入死锁状态?它如何在内部工作?是否因为我们在比C(或C++)更高的级别上进行同步而避免了死锁?任何关于Java中的死锁和同步的文档?
我们在多线程代码中遇到的主要问题是共享数据,我同意并发化过程的目的,并且“正式”发生,在视差化处理期间,线程需要访问以读/写共享数据。
java synchroniz 关键字允许执行以下操作:
它告诉 JVM 在对象的监视器或同步代码段上放置一个锁,这使其能够独占访问该部分代码或对象。
下面是单例的一个示例:
public class Singleton {
private Singleton INSTANCE;
private Singleton() {
}
public Singleton getInstance() {
if (null == INSTANCE) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
这个单例不是线程安全的,如果一个线程试图获取一个实例,而另一个线程也在尝试做同样的事情(争用条件),则可能发生这样的情况:在线程号一完成实例创建之前,第二个线程已经可以访问该方法并创建自己的单例实例,这意味着在T时间我们应该有两个单例实例(称为当时的多顿)。getInstance()
为了解决这个问题,我们必须同步单例的创建行为,这可以通过本身的if语句上方的关键字来完成:synchronized
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 的任何访问,直到线程 1 完成其请求。
也有不同的方法可以实现这一目标,之前引用的书是学习的极好来源,javadoc也是如此。