JUC多线程八锁问题
1. 两个同步方法,一个对象调用,中间延时1毫秒,先发短信还是先打电话? 结果:发短信
- synchronized 修饰普通方法锁的是对象;
- 两个方法是同一把对象锁,发短信先拿到锁,所以先发短信,并不是因为执行顺序和延时导致的打电话比较晚;
import java.util.concurrent.TimeUnit;
public class EightLock {
public static void main(String[] args) {
Phone phone = new Phone();
// 发短信 ()->{} lambda 表达式,JDK8 新特性,作用等同于匿名接口实现类
/*
new Thread(new Runnable() {
@Override
public void run() {
phone.send();
}
}).start();
*/
new Thread(()->{
phone.send();
}).start();
try {
// 延时 1 ms
TimeUnit.MILLISECONDS.sleep(1);
} catch (Exception e) {}
// 打电话
new Thread(()->{
phone.call();
}).start();
}
}
/** 手机类 */
class Phone {
public synchronized void send() {
System.out.println("发短信");
}
public synchronized void call() {
System.out.println("打电话");
}
}
/*
发短信
打电话
*/
2. 两个同步方法,一个对象调用,先发短信还是先打电话? 结果:发短信
- 两个方法是同一把对象锁,谁先拿到就先执行,即便有sleep(),也抱着锁睡觉 ,打电话需要等待发短信完成;
import java.util.concurrent.TimeUnit;
public class EightLock {
public static void main(String[] args) {
Phone phone = new Phone();
// 发短信
new Thread(()->{
phone.send();
}).start();
// 打电话
new Thread(()->{
phone.call();
}).start();
}
}
/** 手机类 */
class Phone {
public synchronized void send() {
try {
// 延时 3 ms
TimeUnit.MILLISECONDS.sleep(3);
} catch (Exception e) {}
System.out.println("发短信");
}
public synchronized void call() {
System.out.println("打电话");
}
}
/*
发短信
打电话
*/
3. 一个同步方法,一个普通方法,一个对象调用,先发短信还是打电话? 结果:打电话
- 普通方法没有锁,不需要获取锁,打电话不用等待;
package com.simple.juc;
import java.util.concurrent.TimeUnit;
public class EightLock {
public static void main(String[] args) {
Phone phone = new Phone();
// 发短信
new Thread(()->{
phone.send();
}).start();
// 打电话
new Thread(()->{
phone.call();
}).start();
}
}
/** 手机类 */
class Phone {
public synchronized void send() {
try {
// 延时 3 ms
TimeUnit.MILLISECONDS.sleep(3);
} catch (Exception e) {}
System.out.println("发短信");
}
public void call() {
System.out.println("打电话");
}
}
/*
打电话
发短信
*/
4. 两个同步方法,两个对象调用,先发短信还是打电话? 结果:打电话
- 两个方法是两把不同的对象锁,互不影响,打电话不用等待;
import java.util.concurrent.TimeUnit;
public class EightLock {
public static void main(String[] args) {
Phone phone1 = new Phone();
Phone phone2 = new Phone();
// 发短信
new Thread(()->{
phone1.send();
}).start();
// 打电话
new Thread(()->{
phone2.call();
}).start();
}
}
/** 手机类 */
class Phone {
public synchronized void send() {
try {
// 延时 3 ms
TimeUnit.MILLISECONDS.sleep(3);
} catch (Exception e) {}
System.out.println("发短信");
}
public synchronized void call() {
System.out.println("打电话");
}
}
/*
打电话
发短信
*/
5. 两个静态同步方法,一个对象调用,先发短信还是打电话? 结果:发短信
- synchronized 修饰静态方法锁class类模板;
- 两个方法是同一把类锁,发短信先拿类锁,打电话需要等待;
import java.util.concurrent.TimeUnit;
public class EightLock {
public static void main(String[] args) {
Phone phone = new Phone();
// 发短信
new Thread(()->{
phone.send();
}).start();
// 打电话
new Thread(()->{
phone.call();
}).start();
}
}
/** 手机类 */
class Phone {
public static synchronized void send() {
try {
// 延时 3 ms
TimeUnit.MILLISECONDS.sleep(3);
} catch (Exception e) {}
System.out.println("发短信");
}
public static synchronized void call() {
System.out.println("打电话");
}
}
/*
发短信
打电话
*/
6. 两个静态同步方法,两个对象调用,先发短信还是打电话? 结果:发短信
- 两个方法是同一把类锁,虽然对象不同,但是同一个类,需要同一把锁,打电话需要等待;
import java.util.concurrent.TimeUnit;
public class EightLock {
public static void main(String[] args) {
Phone phone1 = new Phone();
Phone phone2 = new Phone();
// 发短信
new Thread(()->{
phone1.send();
}).start();
// 打电话
new Thread(()->{
phone2.call();
}).start();
}
}
/** 手机类 */
class Phone {
public static synchronized void send() {
try {
// 延时 3 ms
TimeUnit.MILLISECONDS.sleep(3);
} catch (Exception e) {}
System.out.println("发短信");
}
public static synchronized void call() {
System.out.println("打电话");
}
}
/*
发短信
打电话
*/
7. 一个静态同步方法,一个同步方法,一个对象调用,先发短信还是打电话? 结果:打电话
- 两个方法是两把不同的锁,一个是类锁,一个是对象锁,互不影响,打电话不用等待;
import java.util.concurrent.TimeUnit;
public class EightLock {
public static void main(String[] args) {
Phone phone = new Phone();
// 发短信
new Thread(()->{
phone.send();
}).start();
// 打电话
new Thread(()->{
phone.call();
}).start();
}
}
/** 手机类 */
class Phone {
public static synchronized void send() {
try {
// 延时 3 ms
TimeUnit.MILLISECONDS.sleep(3);
} catch (Exception e) {}
System.out.println("发短信");
}
public synchronized void call() {
System.out.println("打电话");
}
}
/*
打电话
发短信
*/
8. 一个静态同步方法,一个同步方法,两个对象调用,先发短信还是打电话? 结果:打电话
- 两个方法是两把不同的锁,一个是类锁,一个是对象锁,互不影响;
import java.util.concurrent.TimeUnit;
public class EightLock {
public static void main(String[] args) {
Phone phone1 = new Phone();
Phone phone2 = new Phone();
// 发短信
new Thread(()->{
phone1.send();
}).start();
// 打电话
new Thread(()->{
phone2.call();
}).start();
}
}
/** 手机类 */
class Phone {
public static synchronized void send() {
try {
// 延时 3 ms
TimeUnit.MILLISECONDS.sleep(3);
} catch (Exception e) {}
System.out.println("发短信");
}
public synchronized void call() {
System.out.println("打电话");
}
}
/*
打电话
发短信
*/