当我同步非静态方法和静态方法时,行为保持不变。在这两种情况下,当我都使用synced(Task.class)时,线程会同时为静态和非staitc方法锁定实例
public class ThreadDemo {
public static void main(String[] args) {
for(int i=0;i<10;i++){
Task task =new Task();
new Thread(task).start();
}
}
}
class Task implements Runnable {
@Override
public void run() {
printThreadName();
}
public void printThreadName() {
synchronized (Task.class) {
System.out.println("Starting-->"+Thread.currentThread().getName());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Ending->"+Thread.currentThread().getName());
}
}
}
并使方法静态化之后
public static void printThreadName() {
synchronized (Task.class) {
System.out.println("Starting-->"+Thread.currentThread().getName());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Ending->"+Thread.currentThread().getName());
}
}
每个线程都会锁定该类,直到完成为止,依此类推。 我的问题是,为什么在第一种情况下,即使对于非静态方法,此行为也是如此。
答案 0 :(得分:0)
我将总结以上评论:
JLS指出以下内容: (我强调)
如果该方法是 instance方法,它将锁定与为其调用了它的 instance 关联的监视器(即,将被称为this的对象在执行方法主体期间)。如果该方法是 static ,则它将锁定与 Class对象相关联的监视器,该对象代表定义该方法的类。
因此这将在实例上同步:
public synchronized void someMethod() { ... }
这将在课程上同步:
public static synchronized void someMethod() { ... }
当在内部使用同步块 时,您需要提供一种可以是类(例如Myclass.class
)或任何对象实例(可以是{{1})的监视器。 }):
this
您可以使用synchronized(monitor) { ... }
或synchronized(getClass())
来获得与方法级同步非常相似的行为(我不确定synchronized(this)
变体在所有情况下的行为是否相同)。 / p>