我有一点困惑.请看下面的代码.
public class ThreadDemo {
//non-static synchronized method
synchronized void a(){
actBusy();
}
//static synchronized method
static synchronized void b(){
actBusy();
}
//static method
static void actBusy(){
try{
Thread.sleep(1000);
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
final ThreadDemo x = new ThreadDemo();
final ThreadDemo y = new ThreadDemo();
Runnable runnable = new Runnable() {
public void run() {
int option = (int) (Math.random() * 4);
switch (option){
case 0: x.a();
break;
case 1: x.b();
break;
case 2: y.b();
break;
case 3: y.b();
break;
}
}
} ;
Thread t1 = new Thread(runnable);
Thread t2 = new Thread(runnable);
t1.start();
t2.start();
}
}
我确信可以调用这个序列.
x.a() //in Thread-1
y.b() //in Thread-2
虽然我仍然有一点混乱,但我们可以很容易地看到x.a()也调用actBusy()方法
这是一个
静态方法.方法b()是一个调用非同步的静态同步方法
静态方法.当thread-2获得类级别锁定时,为什么从Thread-1调用actBusy()
没被封锁?
我只是在逻辑上混淆,如果一个线程得到一个类级锁,那个类别
非同步静态方法保持打开状态,可以从其他方法(实例方法)调用.为什么?
解决方法:
actBusy()本身不是同步的,但调用方法是.
因此,线程1不会阻塞,因为它获取此对象的锁定,并且没有其他线程对此持有锁定,因此它可以毫无问题地调用它.
这是因为非静态同步方法锁定了当前实例,而不是类对象.
x.a()抓取当前实例的锁,即x,并且没有其他线程能够输入x的方法a(),直到当前线程释放锁.
线程1 – > x.a()//获取锁并保存它
线程2 —> x.a()//阻塞此处,直到线程1释放对x的锁定
编辑:
Class Object != Instance
因此根据JMM,它们是不同的对象,并且两个线程不会相互干扰.所以它允许你调用它.
编辑2:
why does it allow calls to other static methods? Any logic behind it?
假设这个:
public static synchronized int statefulMethod(){
//this should be protected
}
public static int nonStatefulMethod(){
//Just returns a static value such as 5
//so this is thread safe as it does not have any state
}
public static synchronized int otherStatefulMethod(){
//this should also be thread safe
}
因此,如果线程1在方法statefulMethod()中有一些共享状态要保护,那么它使用类级别锁定.现在线程2调用nonStatefulMethod()然后它不应该逻辑阻塞,因为该方法是线程安全的,并且没有必要在此处进行该线程阻塞.
现在,如果线程3调用otherStatefulMethod()而线程1持有类锁,那么线程3必须等待,因为该方法也是静态同步的.
标签:java,multithreading
来源: https://codeday.me/bug/20190718/1492561.html