- 看以下代码,有一个 phone 对象,A、B 线程分别调用该对象的方法,问两个方法谁先调用?答:先发短信再打电话,因为 synchronized 锁住的是 phone 对象(锁的对象是方法调用者)。
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
new Thread(() -> {
phone.sendMsg();
}, "A").start();
new Thread(() -> {
phone.call();
}, "B").start();
}
class Phone {
synchronized void sendMsg() {
System.out.println("发短信");
}
synchronized void call() {
System.out.println("打电话");
}
}
- 看以下代码,有一个 phone 对象,A、B 线程分别调用该对象的方法,问两个方法谁先调用?答:先发短信再打电话,理由还是 synchronized 锁住的是 phone 对象,从 A 线程开始执行方法时到 A 执行完毕,B 线程一定会等待 4 秒。
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
new Thread(() -> {
phone.sendMsg();
}, "A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
phone.call();
}, "B").start();
}
class Phone {
synchronized void sendMsg() {
try {
TimeUnit.SECONDS.sleep(3);
System.out.println("发短信");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized void call() {
System.out.println("打电话");
}
}
- 看以下代码,一个对象,俩线程分别执行有锁和无锁的方法,问两个方法谁先调用?答:先打电话再发短信,没有加锁的方法不受锁的影响,该调用还是调用。
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
new Thread(() -> {
phone.sendMsg();
}, "A").start();
new Thread(() -> {
phone.call();
}, "B").start();
}
class Phone {
synchronized void sendMsg(){
try {
TimeUnit.SECONDS.sleep(3);
System.out.println("发短信");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
void call() {
System.out.println("打电话");
}
}
- 看以下代码,两个对象,两个线程分别执行有锁和无锁的方法,问两个方法谁先调用?答:先打电话再发短信,当 A 线程开始执行时,等待一秒钟 B 线程的方法就执行,两个对象两把锁,互不影响。
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
phone.sendMsg();
}, "A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
phone2.call();
}, "B").start();
}
class Phone {
synchronized void sendMsg(){
try {
TimeUnit.SECONDS.sleep(3);
System.out.println("发短信");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized void call() {
System.out.println("打电话");
}
}
- 两个线程分别调用两个静态加锁方法,问两个方法谁先调用?答:先发短信再打电话,两个方法加了 static ,上升到类级别,也就是说锁的是 phone 的 class,是一个类对象,在 A 线程调发短信方法时持有该 class,B 线程当然获取不到该 class,必须等待。
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
Phone.sendMsg();
}, "A").start();
new Thread(() -> {
Phone.call();
}, "B").start();
}
class Phone {
static synchronized void sendMsg(){
try {
TimeUnit.SECONDS.sleep(3);
System.out.println("发短信");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static synchronized void call() {
System.out.println("打电话");
}
}
- 两个对象,两个线程分别调用两个静态加锁方法,问两个方法谁先调用?答:还是发短信再打电话,锁的是 phone 的类对象,两个 phone 对象所属的 class 是一致的,在 A 线程调发短信方法时持有该 class,B 线程获取不到该 class,必须等待。
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
phone.sendMsg();
}, "A").start();
new Thread(() -> {
phone2.call();
}, "B").start();
}
class Phone {
static synchronized void sendMsg(){
try {
TimeUnit.SECONDS.sleep(3);
System.out.println("发短信");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static synchronized void call() {
System.out.println("打电话");
}
}
- 一个对象,先调用静态加锁方法,再调用成员加锁方法,问两个方法谁先调用?答:先打电话再发短信,加了 static 方法锁的对象是 phone 的 class,而未加 static 的方法锁的是原本的 phone 对象,锁的对象不同,并不互斥。
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
new Thread(() -> {
phone.sendMsg();
}, "A").start();
new Thread(() -> {
phone.call();
}, "B").start();
}
class Phone {
static synchronized void sendMsg(){
try {
TimeUnit.SECONDS.sleep(3);
System.out.println("发短信");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized void call() {
System.out.println("打电话");
}
}
- 两个对象,先调用静态加锁方法,再调用成员加锁方法,问两个方法谁先调用?答:还是打电话再发短信,static 方法锁的是 class 对象,未加 static 的方法锁的是 phone2 对象,并不互斥。
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
phone.sendMsg();
}, "A").start();
new Thread(() -> {
phone2.call();
}, "B").start();
}
class Phone {
static synchronized void sendMsg(){
try {
TimeUnit.SECONDS.sleep(3);
System.out.println("发短信");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized void call() {
System.out.println("打电话");
}
}