[英]Synchronised instance methods in java
从某些互联网来源
这是一个同步实例方法:
public synchronized void add(int value){
this.count += value;
}
注意在方法声明中使用了synced关键字。 这告诉Java该方法是同步的。 Java中的同步实例方法在拥有该方法的实例(对象)上同步。 因此,每个实例在不同的对象(拥有实例)上具有同步的同步方法。 在同步实例方法内部只能执行一个线程。 如果存在多个实例,则每个实例可以一次在一个同步实例方法中执行一个线程。 每个实例一个线程。
这是我的理解。 如果我有一个可运行的对象,其中包含包含上述add方法的类的实例,则
情况1:我有两个线程,每个线程具有包含add方法的类的相同实例,那么一次只能执行一个上述add方法。 因此,如果一个线程调用add
那么在完成执行之前不能抢占它吗?
情况2:如果我的两个线程都具有包含add方法的类的两个不同实例,则在这种情况下,它的同步实际上不会发挥任何作用。 他们两个将执行,好像根本没有应用同步。
我的理解正确吗?
是的,但是
那么在完成执行之前不能抢占吗?
锁不会阻止线程被抢占,但会阻止其他任何线程获得相同的锁。 也就是说,即使线程可以在按住锁的状态下短时停止,它看起来也一样。
好像根本没有应用同步。
不同之处在于,如果没有synchronized
,它将更快。 由于它是如此简单的操作。 如果您做的事情不那么琐碎,则同步的成本将相对较小。 无论如何,在几乎所有情况下,正确性都比速度更重要。
您的理解在很大程度上是正确的。 (请参阅彼得的回答)。
这是一个(愚蠢的)示例。
public class Person {
private String firstName = "?"; // set an initial value
private String lastName = "?";
public void setName(String first, String last) {
this.firstName = first;
this.lastName = last;
}
public String toString() {
return firstName + " " + lastName ;
}
}
由于这两种方法都不同步,因此,如果一个线程同时调用setName("John", "Doe")
,而另一个线程同时调用toString()
,则setName
可能在中间被抢占,而toString 可能被抢占()被调用,名称只能是“ half-set”。 因此toString()
可以打印“ John?”。
如果两个方法都同步,则对toString()
的调用将完全在 setName()
的调用之前或之后进行。 如果setName()在中间被抢占,则toString()将等待直到setName完成。 因此toString()
要么打印“ ??” 或“ John Doe”。
Java内存模型也可能需要同步,以确保一个线程中所做的更改被另一线程看到。 但这正在变得更加先进...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.