两个线程调用两个不同的方法,一个是静态的,另一个是非静态的,但是当我从方法中删除静态时,我得到的输出与之前的输出不同,这与我在/从两者中放入/删除静态时的输出相同方法比我得到不同的输出。为什么呢?
public static void main(String[] args) {
Hello h = new Hello();
AThread th1 = new AThread(h);
BThread th2 = new BThread(h);
th1.start();
th2.start();
}
还有两个不同的Thread类AThread& BThread来自Hello类的调用方法。
public class AThread extends Thread {
Hello h;
public AThread(Hello h) {
this.h = h;
}
public void run() {
h.show();
}
}
public class BThread extends Thread {
Hello h;
public AThread(Hello h) {
this.h = h;
}
public void run() {
h.display();
}
}
public class Hello {
static synchronized void show() {
Thread th = Thread.currentThread();
for (int i = 0; i < 10; i++) {
System.out.println("SHOW\t:" + th.getName() + "\t" + i);
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
}
}
static synchronized void display() {
Thread th = Thread.currentThread();
for (int i = 100; i < 110; i++) {
System.out.println("Disp\t:" + th.getName() + "\t" + i + "\t");
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
输出: - 当我放置静态或当我从两种方法中删除静态时 -
SHOW :Thread-0 0
SHOW :Thread-0 1
SHOW :Thread-0 2
....
SHOW :Thread-0 9
Disp : Thread-1 100
Disp :Thread-1 101
....
Disp :Thread-1 109
当我在第一种方法中放置静态并从第二种方法中删除静态时 -
Disp :Thread-1 100
SHOW :Thread-0 0
Disp :Thread-1 101
SHOW :Thread-0 1
Disp :Thread-1 102
SHOW :Thread-0 2
Disp :Thread-1 103
SHOW :Thread-0 3
....
Disp :Thread-1 109
答案 0 :(得分:1)
从类中调用synchronized
方法时,正在执行该工作的线程会锁定该对象。这种方式在任何时候都只会调用一个synchronized
方法,其他线程将等待获取对象的锁定。
重要的是要知道,对于非静态同步方法,线程获取对象的实际实例的锁(在您的情况下 - 对象<强>ħ强>)
所以当你使用两个非静态synchronized
方法时,它们会被同步化,输出首先是“SHOW”,第二个是“DISP”(反之亦然)。
但是,当您使用静态同步方法时,线程获取CLASS ITSELF的锁定(在您的情况下 - Hello )
因此,当你使用两个静态同步方法时,它们是同步的,输出首先是“SHOW”,第二个是“DISP”(反之亦然)。
最后但并非最不重要 - 当你使用非静态和静态同步方法时,第一个线程获取实例的锁(h),第二个线程获取类的锁(Hello) - 这是两个不同的锁,这意味着两个线程可以异步执行这些方法。这就是你收到混合结果的原因。