Java多线程混乱
代码示例1:Java多线程混乱,java,multithreading,synchronize,Java,Multithreading,Synchronize,代码示例1: class Test { MyObj myObj = new MyObj(); public void test() { // doing my other stuff synchronized (myObj) { // accessing myObj } } } class Test { MyObj myObj = new MyObj(); public void
class Test {
MyObj myObj = new MyObj();
public void test() {
// doing my other stuff
synchronized (myObj) {
// accessing myObj
}
}
}
class Test {
MyObj myObj = new MyObj();
public void test() {
synchronized (myObj) {
// doing my other stuff
// accessing myObj
}
}
}
class Test {
MyObj myObj = new MyObj();
public synchronized void test() {
// doing my other stuff
// accessing myObj
}
}
代码示例2:
class Test {
MyObj myObj = new MyObj();
public void test() {
// doing my other stuff
synchronized (myObj) {
// accessing myObj
}
}
}
class Test {
MyObj myObj = new MyObj();
public void test() {
synchronized (myObj) {
// doing my other stuff
// accessing myObj
}
}
}
class Test {
MyObj myObj = new MyObj();
public synchronized void test() {
// doing my other stuff
// accessing myObj
}
}
代码示例3:
class Test {
MyObj myObj = new MyObj();
public void test() {
// doing my other stuff
synchronized (myObj) {
// accessing myObj
}
}
}
class Test {
MyObj myObj = new MyObj();
public void test() {
synchronized (myObj) {
// doing my other stuff
// accessing myObj
}
}
}
class Test {
MyObj myObj = new MyObj();
public synchronized void test() {
// doing my other stuff
// accessing myObj
}
}
我想在上面的代码快照中保持对myObj的线程安全。那么,上面哪种代码快照更可取?为什么 代码示例1是合适的。
因为先锁定对象,然后再执行其他操作是不合适的。代码示例1是合适的。
因为先锁定对象,然后再执行其他操作是不合适的。根据我在开源项目中看到的代码,第一个代码示例更好,因为当您不再需要对象时,可以释放它,以便其他线程可以访问它。根据我在开源项目中看到的代码,第一个代码示例更好,因为当您不再需要对象时,可以释放它,以便其他线程可以访问它。您的示例中没有一个包含足够的信息 数据在哪里?不变量是什么?线程何时/何地/如何访问数据 “线程安全”没有数据就没有意义。有状态类的文档通常会保证其方法如何提升实例的状态。“线程安全”意味着即使在多个线程调用这些方法时,也能满足这些保证。但是如果类不是有状态的,或者没有这样的保证,那么“线程安全”就没有任何意义
注意:代码示例1与其他示例相比有一个重要的优势:互斥(即
synchronized
块)更小。根据经验,您希望互斥体尽可能小。如果“my other stuff”不关心受互斥体保护的数据,那么它就不应该发生在互斥体中,因为这会阻止其他线程访问数据,并且不会因为任何有用的原因而阻止它们
p.p.S.:@Ordous注释+1:除非您能看到可以修改或检查状态的每个代码块,否则无法知道某个对象的状态是否是线程安全的。由于在您的示例中,
myObj
不是private
,因此我们必须假设其他地方有代码可以修改或检查其状态。由于我们看不到该代码,我们必须假设myObj
不是线程安全的。您的示例中没有一个包含足够的信息
数据在哪里?不变量是什么?线程何时/何地/如何访问数据
“线程安全”没有数据就没有意义。有状态类的文档通常会保证其方法如何提升实例的状态。“线程安全”意味着即使在多个线程调用这些方法时,也能满足这些保证。但是如果类不是有状态的,或者没有这样的保证,那么“线程安全”就没有任何意义
注意:代码示例1与其他示例相比有一个重要的优势:互斥(即
synchronized
块)更小。根据经验,您希望互斥体尽可能小。如果“my other stuff”不关心受互斥体保护的数据,那么它就不应该发生在互斥体中,因为这会阻止其他线程访问数据,并且不会因为任何有用的原因而阻止它们
p.p.S.:@Ordous注释+1:除非您能看到可以修改或检查状态的每个代码块,否则无法知道某个对象的状态是否是线程安全的。由于在您的示例中,
myObj
不是private
,因此我们必须假设其他地方有代码可以修改或检查其状态。因为我们看不到那个代码,所以我们必须假设myObj
不是线程安全的。在整个方法上保持一个锁(如果它很长)是非常昂贵的。它不仅可以阻止整个威胁,还可以阻止不需要同步的代码。其次,有时您可能不使用您的myObj
,在这种情况下,示例2和3将是不好的
简而言之:仅同步块的一部分,即您正在处理对象的位置。您还可以在对象上使用volatile
,检查其值,而无需同步块。请记住,锁定可能代价高昂
但是,当您的方法足够短,或者只包含带有myObj的代码时,将整个方法同步是一个很好的解决方案
public void test() {
// doing my other stuff, not concernign myObj
synchronized (myObj) {
// do things with myObj (read/write)
}
// doing my other stuff, not concernign myObj
}
看看这个例子。在整个方法上保持一个锁(如果它很长的话)是非常昂贵的。它不仅可以阻止整个威胁,还可以阻止不需要同步的代码。其次,有时您可能不使用您的
myObj
,在这种情况下,示例2和3将是不好的
简而言之:仅同步块的一部分,即您正在处理对象的位置。您还可以在对象上使用volatile
,检查其值,而无需同步块。请记住,锁定可能代价高昂
但是,当您的方法足够短,或者只包含带有myObj的代码时,将整个方法同步是一个很好的解决方案
public void test() {
// doing my other stuff, not concernign myObj
synchronized (myObj) {
// do things with myObj (read/write)
}
// doing my other stuff, not concernign myObj
}
看看这个例子。首选代码示例1。代码示例1-->监视器是在myObj上获得的,因此它是线程安全的代码示例2-->监视器是在myObj上获得的,因此它是线程安全的,内部或外部的其他内容是不相关的代码示例3-->锁/监视器是在调用test()方法的对象上获得的,无论是myObj还是任何其他对象,取决于调用,这些都不是首选项,因为您将
myObj
package protected而不是private=PCode示例1作为首选项。代码示例1-->监视器是在myObj上获得的,因此它是线程安全的代码示例2-->监视器是在myObj上获得的,因此它是线程安全的,内部或外部的其他内容是不相关的代码示例3-->锁/监视器是在调用test()方法的对象上获得的,无论是myObj还是任何其他对象,