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

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


当前回答

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

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

考虑一下:

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

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

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

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

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

其他回答

synchronized是Java中的关键字,用于在多线程环境中使发生在关系之前,以避免内存不一致和线程干扰错误。

以我的理解,同步基本上意味着编译器编写一个监视器。进入并监控。在方法周围退出。因此,它可能是线程安全的,这取决于它是如何使用的(我的意思是,你可以编写一个具有同步方法的对象,它不是线程安全的,这取决于你的类做什么)。

Synchronized的意思是,如果在特定对象上使用Synchronized块,那么与单个对象关联的多个线程可以防止脏读写。为了让你更清楚,让我们举个例子:

class MyRunnable implements Runnable {
    int var = 10;
    @Override
    public void run() {
        call();
    }

    public void call() {
        synchronized (this) {
            for (int i = 0; i < 4; i++) {
                var++;
                System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
            }
        }
    }
}

public class MutlipleThreadsRunnable {
    public static void main(String[] args) {
        MyRunnable runnable1 = new MyRunnable();
        MyRunnable runnable2 = new MyRunnable();
        Thread t1 = new Thread(runnable1);
        t1.setName("Thread -1");
        Thread t2 = new Thread(runnable2);
        t2.setName("Thread -2");
        Thread t3 = new Thread(runnable1);
        t3.setName("Thread -3");
        t1.start();
        t2.start();
        t3.start();
    }
}

我们已经创建了两个MyRunnable类对象,runnable1与线程1和线程3共享,而runnable2仅与线程2共享。 现在,当t1和t3启动时没有使用synchronized, PFB输出表明线程1和线程3同时影响var值,而对于线程2,var有自己的内存。

Without Synchronized keyword

    Current Thread Thread -1 var value 11
    Current Thread Thread -2 var value 11
    Current Thread Thread -2 var value 12
    Current Thread Thread -2 var value 13
    Current Thread Thread -2 var value 14
    Current Thread Thread -1 var value 12
    Current Thread Thread -3 var value 13
    Current Thread Thread -3 var value 15
    Current Thread Thread -1 var value 14
    Current Thread Thread -1 var value 17
    Current Thread Thread -3 var value 16
    Current Thread Thread -3 var value 18

使用Synchronzied,线程3在所有场景中等待线程1完成。有两个锁,一个在runnable1上,由线程1和线程3共享,另一个在runnable2上,仅由线程2共享。

Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -1 var value 12
Current Thread Thread -2 var value 12
Current Thread Thread -1 var value 13
Current Thread Thread -2 var value 13
Current Thread Thread -1 var value 14
Current Thread Thread -2 var value 14
Current Thread Thread -3 var value 15
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 17
Current Thread Thread -3 var value 18

synchronized关键字是关于不同的线程读写相同的变量、对象和资源。这在Java中不是一个微不足道的话题,但这里引用Sun的一段话:

同步方法可以实现简单的 防止线程的策略 干扰和记忆一致性 错误:如果对象是可见的 多于一个线程,全部读取或 写入该对象的变量为 通过同步方法完成。

简而言之:当你有两个线程读写同一个“资源”时,比如说一个名为foo的变量,你需要确保这些线程以原子的方式访问变量。如果没有synchronized关键字,线程1可能看不到线程2对foo所做的更改,或者更糟的是,它可能只改变了一半。这不是你逻辑上所期望的。

同样,这在Java中是一个重要的主题。要了解更多,请在这里探索关于SO和互联网的主题:

并发性 Java内存模型

继续探索这些话题,直到“Brian Goetz”这个名字在你的脑海中与“并发性”这个术语永久地联系在一起。

Java同步

volatile[About] => synchronized

synchronized块在Java中是多线程中的监视器。同一对象/类的同步块只能由单个线程执行,其他的都在等待。它可以帮助解决竞赛状况。

Java 5通过支持happens-before扩展了同步[关于]

监视器的解锁(同步块或方法退出)发生在同一监视器的每个后续锁定(同步块或方法进入)之前。

下一步是java.util.concurrent