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

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

希望能有所帮助

其他回答

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

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

Object.wait()

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

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

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

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

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

考虑一下:

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

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

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

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

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

概述

Java中的Synchronized关键字与线程安全有关,也就是说,当多个线程读或写同一个变量时。 这可以直接发生(通过访问相同的变量)或间接发生(通过使用使用访问相同变量的另一个类的类)。

synchronized关键字用于定义一个代码块,其中多个线程可以以安全的方式访问同一个变量。

更深层次的

从语法上看,synchronized关键字接受一个Object作为它的参数(称为锁对象),然后后面跟着一个{block of code}。

When execution encounters this keyword, the current thread tries to "lock/acquire/own" (take your pick) the lock object and execute the associated block of code after the lock has been acquired. Any writes to variables inside the synchronized code block are guaranteed to be visible to every other thread that similarly executes code inside a synchronized code block using the same lock object. Only one thread at a time can hold the lock, during which time all other threads trying to acquire the same lock object will wait (pause their execution). The lock will be released when execution exits the synchronized code block.

同步的方法:

将synchronized关键字添加到方法定义中等于将整个方法体包装在同步代码块中,锁对象为this(对于实例方法)和ClassInQuestion.getClass()(对于类方法)。

—实例方法是没有静态关键字的方法。 —类方法是具有静态关键字的方法。

技术

如果没有同步,就无法保证以何种顺序进行读写,可能会给变量留下垃圾。 (例如,一个变量可能由一个线程写入一半的比特,另一个线程写入一半的比特,使变量处于两个线程都没有尝试写入的状态,而是两者结合在一起的混乱状态。)

在另一个线程读取之前(时钟时间)完成一个线程的写操作是不够的,因为硬件可能已经缓存了变量的值,读取线程将看到缓存的值,而不是写入它的值。

结论

因此,在Java的情况下,您必须遵循Java内存模型,以确保线程错误不会发生。 换句话说:在底层使用同步、原子操作或为您使用它们的类。

来源 http://docs.oracle.com/javase/specs/jls/se8/html/index.html Java®语言规范,2015-02-13