java 中的同步功能如何工作?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6584355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 16:28:55  来源:igfitidea点击:

How does the synchronize functionality work in java?

javasynchronizationdeadlock

提问by Zonata

Since I've started programming in Java I have been wondering this (about a year or two). In C, we must know the different method to correctly avoid deadlock between thread and thus there is much more choice between synchronization method.

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

So what about Java? When we synchronize, how does it avoid putting thread in deadlock situation? How does it work internally? Does the deadlock are avoided because we synchronized on higher level than in C ( or C++)? Any documentation about deadlock and synchronization in java?

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

回答by Andrew White

Under the hood it is using two opcodes monitorenterand monitorexitat the byte code level which acquire/release locks on a object reference at a JVM global level. I highly recommend you read How the Java virtual machine performs thread synchronization.

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

回答by Abderrazak BOUADMA

The main problem(s) we meet with a multithreaded code is sharing data, and I agree with, the purpose of concurency parallizing process and it happens "ofently" that during parallalized processing that threads need accessing for read/write on shared data.

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

The java synchronized keyword permits the following:

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

It tells the JVM to put a lock on the monitor of the object or the piece of the synchronized code, which gives it exclusive access to that part of code or object.

它告诉 JVM 在对象或同步代码片段的监视器上放置一个锁,这使它可以独占访问该部分代码或对象。

Here's an example of a Singleton:

下面是一个单例的例子:

public class Singleton {
    private Singleton INSTANCE;

    private Singleton() {
    }

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

This Singleton is not thread safe, if a thread is trying to get an instance while another is also trying to do the same (race condition) it may happen that before that the thread number one finishes the creation of the instance the second has already had access to the getInstance()method and created his own instance of the Singleton which means that at a T time we should have two instances of the Singleton (called multiton at that time).

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

To solve this problem we have to synchronize the creational behaviour of the singleton, this may be done by the keyword synchronizedabove the if statement on the INSTANCEitself:

为了解决这个问题,我们必须同步单例的创建行为,这可以通过synchronizedif 语句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;
    }
}

The result is when the first thread asks the Singleton instance and during creation time, the JVM will put a lock on the monitor of the INSTANCE denying any access to the INSTANCE until thread one finished its request.

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

There are diffrent ways to achieve that as well, the book cited before is an excellent source of learning, javadoc also.

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

回答by David R Tribble

Short answers:

简短的答案:

  1. synchronizedmethods and lockblocks use a monitorthat locks the semaphoreof the locked object for the duration of the method or block.

  2. The Java language itself does not prevent deadlocks. That's up to you as the programmer to insure that objects are locked/unlocked in the correct order to prevent contention.

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

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

回答by Jason S

Synchronization isn't really that much easier in Java than in C. Syntacticallyit's easier, because all you need to do for a mutex is declare a method as synchronized or use

Java 中的同步实际上并不比 C 中容易得多。从语法上讲,它更容易,因为您需要为互斥锁做的就是将方法声明为同步或使用

synchronized(someObject)
{
   someCode();
}

Whereas in C/C++, you have to use operating-system-specific functions to use a mutex, or you have to use the Boost library.

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

But the pitfalls about deadlock are all basically the same as in any language.

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

回答by Thomas

Did you try google (Java Deadlock)? First result is this: http://download.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

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

There you can see that with synchronizeddeadlocks still occur, since synchronization is not designed to prevent those in the first place.

在那里您可以看到synchronized死锁仍然会发生,因为同步最初并不是为了防止死锁。

回答by JB Nizet

You also have to take care of deadlocks in Java. The easiest way to get a deadlock is to make one thread run a block synchronized on A, and then another block synchronized on B, while another thread executes a block synchronized on B, and then a block synchronized on A.

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

Read the Java tutorial about concurrency.And if you want to keep learning, read Java concurrency in practice.

阅读有关并发的 Java 教程。如果您想继续学习,请阅读Java concurrency in practice

回答by Snehal

I see some issue with Singleton above. I think that class will never be created. Please consider below code.

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