zig*_*ggy 8 java multithreading scjp
有人可以在对象锁定的上下文中解释这两个例子之间的区别:
public void method1(){
synchronized(this){
....
}
}
Run Code Online (Sandbox Code Playgroud)
和
StringBuffer aStringBufferObject = new StringBuffer("A");
public void method2(){
synchronized(aStringBufferObject){
....
}
}
Run Code Online (Sandbox Code Playgroud)
我知道第一个示例将获取this
实例上的锁,第二个示例将获取aStringBufferObject实例的锁.但我真的不明白两者的影响或区别.
例如,在第二个示例中,线程是否仍然能够执行synchronized块内的代码,因为锁与'this'实例无关?
我知道同步一个方法或一个代码块会阻止多个线程同时访问该块/方法,但指定要锁定的对象的目的是什么,以及指定对象的方式有何不同上面的例子?
指定要锁定的对象的目的是什么?
通常,this
在Class
实例上或实例上更容易同步(对于静态方法).但是,在某些情况下,您需要同步特定对象而不是隐式锁(this
).此类案件包括:
this
.您只能在Object
s上进行同步,因为每个Object
都与Java中的隐式监视器相关联.基元没有这样的隐式监视器,因此您需要使用锁定对象.使用包装器类是一个糟糕且不正确的选择,特别是如果您最终修改了受保护块中的锁定对象.this
不能保证线程安全.例如,如果要同步对ArrayList
跨类实例共享的实例的访问A
,则在实例上进行同步A
是无用的.线程可能会创建新的实例A
并获得对列表的访问权限,而另一个线程正在修改它.如果您使用所有线程必须争用的其他锁,那么您可以保护列表; 这个锁可以是与之关联的锁A.class
,但它可以是任何提供相同保证的对象.以下是拆分锁用法的示例:
private Object method1Lock = new Object();
private Object method2Lock = new Object();
public void method1(){
synchronized(method1Lock){
....
}
}
public void method2(){
synchronized(method2Lock){
....
}
}
Run Code Online (Sandbox Code Playgroud)
如果可以确保并发执行method1
并且method2
不违反类不变量,则可以使用拆分锁.这样,您可以提高需要访问同一对象的线程的性能,但会调用不同的方法.
在你的另一个问题上,
例如,在第二个示例中,线程是否仍然能够执行synchronized块内的代码,因为锁与'this'实例无关?
在第二个示例中,进入受保护区域的任何线程都必须获取与之关联的锁定aStringBufferObject
.如果另一个线程持有该锁,则当前线程将不再继续.指定时this
,线程必须获取与当前对象关联的锁.在这两种情况下,线程都必须获得锁定; 这些示例仅在用作锁的对象中有所不同.
归档时间: |
|
查看次数: |
564 次 |
最近记录: |