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

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


当前回答

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

其他回答

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

Java同步

volatile[About] => synchronized

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

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

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

下一步是java.util.concurrent

下面是来自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是Java中的关键字,用于在多线程环境中使发生在关系之前,以避免内存不一致和线程干扰错误。

What the other answers are missing is one important aspect: memory barriers. Thread synchronization basically consists of two parts: serialization and visibility. I advise everyone to google for "jvm memory barrier", as it is a non-trivial and extremely important topic (if you modify shared data accessed by multiple threads). Having done that, I advise looking at java.util.concurrent package's classes that help to avoid using explicit synchronization, which in turn helps keeping programs simple and efficient, maybe even preventing deadlocks.

ConcurrentLinkedDeque就是这样一个例子。与命令模式一起,它允许通过将命令填充到并发队列中来创建高效的工作线程——不需要显式同步,不可能发生死锁,不需要显式sleep(),只需通过调用take()轮询队列。

简而言之:“内存同步”隐式地发生在线程启动、线程结束、读取volatile变量、解锁监视器(留下同步块/函数)等时候。这种“同步”影响(在某种意义上“刷新”)在该特定操作之前完成的所有写操作。在前面提到的ConcurrentLinkedDeque的情况下,文档“说”:

内存一致性影响:与其他并发集合一样, 对象放入线程之前的操作 ConcurrentLinkedDeque访问之后的happens -before操作 或者从另一个ConcurrentLinkedDeque中删除该元素 线程。

这种隐式行为在某种程度上是有害的,因为大多数没有太多经验的Java程序员会因此而得过其实。然后突然被这个线程绊倒,因为Java在生产中没有做它“应该”做的事情,因为有不同的工作负载——并且很难测试并发性问题。