Java中的易失和同步关键字

时间:2012-12-21 23:10:30

标签: java

  

可能重复:
  Difference between volatile and synchronized in JAVA (j2me)

我对2个java关键字synchronizedvolatile感到困惑。

据我所知,由于java是multi-threaded语言,并且使用关键字synchronized将强制它在1个线程中执行。我是对的吗?

volatile也会做同样的事情吗?

7 个答案:

答案 0 :(得分:6)

volatile和synchronized保证可见性,但synchronized也提供原子性:

  • 如果一个线程线程读取一个volatile变量,它可以保证看到先前对同一个变量的写入,包括它们是否由其他线程完成
  • synchronized块提供相同的保证(假设写入和读取都是在同一个监视器上完成的),但也提供了原子性保证:同步块中的所有指令都将从同一锁上同步的另一个线程看起来是原子的。

答案 1 :(得分:4)

对于longdouble,读写操作不是原子操作。 volatile是一个修饰符,可以放在一个变量上,使读写操作成为原子(包括longdouble

文章Atomic Access获得了更多相关信息。

基本上,它是为了确保如果一个线程更改了变量的值,则其余线程将看到该更改,并且在写入时将无法读取它。

答案 2 :(得分:2)

Java多线程涉及两个问题,确保可以一致地完成多个操作,而不会混合不同线程的操作,并且可以将变量值的更改用于除执行更改之外的线程。

实际上,变量自然不存在于硬件中的单个位置。可能存在不同线程的内部状态或不同硬件高速缓存中的副本。简单地分配给变量会自动从执行赋值的线程的角度更改其值。

如果变量标记为“volatile”,则其他线程将获得更改的值。

“synchronized”还可确保更改变为可见。具体来说,在同步块结束之前在一个线程中完成的任何更改都将对同一对象上同步的后续块中的另一个线程执行的读取可见。

此外,在同一对象上同步的块被强制顺序运行,而不是并行运行。这允许人们做一些事情,比如在变量中添加一个变量,知道它的值在读取旧值和写入新值之间不会改变。它还允许对多个变量进行一致的更改。

我知道在Java中编写可靠的并发代码所需的最佳方法是阅读Java Concurrency in Practice

答案 3 :(得分:1)

本质上,volatile用于表示变量的值将被不同的线程修改。

Synchronized是一个关键字,其总体目的是一次只允许一个线程进入特定的代码段,从而允许我们保护,例如,变量或数据不被来自不同线程的同时修改所破坏。

答案 4 :(得分:1)

它与Java Memory Model中描述的冗长一样复杂。

答案 5 :(得分:1)

同步意味着在给定时间只有一个线程可以访问方法或代码块。

Volatile处理线程之间的通信。这是一个很好的解释:http://jeremymanson.blogspot.be/2008/11/what-volatile-means-in-java.html

答案 6 :(得分:0)

Volatile关键字将使每个线程在内存位置读取或写入原子操作。如果你不使用volatile,那么线程可以缓存该变量,并且线程可能正在读/写缓存副本而不是实际副本。