我有一些关于同步关键字的用法和意义的问题。

synchronized关键字有什么意义? 什么时候应该同步方法? 它在程序上和逻辑上意味着什么?


当前回答

同步法等效于正常方法 同步语句(使用此语句)

class A {
    public synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(this) {
             // all function code
        }
    } 
}

同步静态方法等价于Synchronized语句(使用类)

class A {
    public static synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(A.class) {
             // all function code
        }
    } 
}

同步语句(使用变量)

class A {
    private Object lock1 = new Object();

    public void methodA() {
        synchronized(lock1 ) {
             // all function code
        }
    } 
}

对于同步,我们有同步方法和同步语句。然而,同步方法类似于同步语句,所以我们只需要理解同步语句。

基本上,我们会有

synchronized(object or class) { // object/class use to provides the intrinsic lock
   // code 
}

这里有2个想法,有助于理解同步

每个对象/类都有一个与之相关的内在锁。 当线程调用同步语句时,它会自动获取同步语句对象的内在锁,并在方法返回时释放锁。只要一个线程拥有一个内在锁,其他线程就不能获得相同的锁=>线程安全。

= > 当线程a调用synchronized(this){// code 1} =>时,所有synchronized(this)的块代码(类内)和所有synchronized的正常方法(类内)都被锁定,因为是SAME锁。它将在线程A解锁("// code 1"完成)后执行。

此行为类似于synchronized(变量){// code 1}或synchronized(类)。

SAME LOCK =>锁(不依赖于哪个方法?或者哪些陈述?)

使用同步方法还是同步语句?

我更喜欢同步语句,因为它更易于扩展。例如,在将来,你只需要同步方法的一部分。例如,你有两个synchronized方法,它们之间没有任何关联,但是当一个线程运行一个方法时,它会阻塞另一个方法(它可以通过使用synchronized(一个变量)来防止)。

然而,应用同步方法很简单,代码看起来很简单。对于某些类,只有一个同步方法,或者类中所有同步方法彼此相关=>,我们可以使用同步方法使代码更短,更容易理解

Note

(它与同步无关,它是对象与类或非静态与静态之间的区别)。

当你使用synchronized或普通方法或synchronized(this)或synchronized(非静态变量)时,它将基于每个对象实例进行同步。 当你使用synchronized或静态方法或synchronized(类)或synchronized(静态变量)时,它将基于类进行同步

参考

https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

希望能有所帮助

其他回答

下面是来自Java教程的解释。

考虑下面的代码:

public class SynchronizedCounter { private int c = 0; public synchronized void increment() { c++; } public synchronized void decrement() { c--; } public synchronized int value() { return c; } } if count is an instance of SynchronizedCounter, then making these methods synchronized has two effects: First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object. Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.

synchronized关键字可以防止多个线程并发访问一个代码块或对象。Hashtable的所有方法都是同步的,因此一次只有一个线程可以执行其中的任何方法。

当使用非同步结构(如HashMap)时,必须在代码中构建线程安全特性以防止一致性错误。

Synchronized simple意味着没有两个线程可以同时访问块/方法。当我们说一个类的任何块/方法都是同步的,这意味着一次只有一个线程可以访问它们。在内部,试图访问它的线程首先在该对象上获得一个锁,只要这个锁不可用,其他线程就不能访问该类实例的任何同步方法/块。

注意,另一个线程可以访问同一对象的方法,该方法没有被定义为同步。线程可以通过调用来释放锁

Object.wait()

synchronized关键字使线程在输入方法时获得锁,以便同一时间只有一个线程可以执行该方法(对于给定的对象实例,除非它是静态方法)。

这通常被称为使类线程安全,但我认为这是一种委婉说法。虽然同步确实可以保护Vector的内部状态不被破坏,但这通常对Vector的用户没有太大帮助。

考虑一下:

 if (vector.isEmpty()){
     vector.add(data);
 }

尽管所涉及的方法是同步的,但由于它们分别被锁定和解锁,两个不幸计时的线程可以创建具有两个元素的向量。

所以实际上,你也必须在你的应用程序代码中同步。

因为方法级同步是a)当你不需要它的时候很昂贵,b)当你需要同步的时候不够用,所以现在有了不同步的替换(Vector的情况下是ArrayList)。

最近,并发包已经发布,其中包含许多处理多线程问题的聪明实用程序。

你可以把它想象成一个转门,就像你在足球场看到的那样。有平行的人群想要进入,但在旋转门他们是“同步的”。一次只能有一个人通过。所有想要通过的人都可以,但他们可能要等到他们能够通过。