11. 如何实现子线程先执行,主线程再执行?(⭐)
启动子线程后,立即调用该线程的join()方法,则主线程必须等待子线程执行完成后再执行。
12. 阻塞线程的方式有哪些?(⭐)
当发生如下情况时,线程将会进入阻塞状态:
- 线程调用sleep()方法主动放弃所占用的处理器资源;
- 线程调用了一个阻塞式IO方法,在该方法返回之前,该线程被阻塞;
- 线程调用wait方法,等待通知;
13. 说一说synchronized与Lock的区别(⭐)
- 范围:synchronized是Java内部的关键字,只能用于方法和代码块中,而Lock是Java的一个类,在程序中可以通过创建Lock的实例来实现同步控制。
- 粒度:synchronized的粒度较粗,是整个方法或代码块,而Lock的粒度较细,可以实现更细粒度的同步控制。
- 接口:synchronized是隐式的,它由编译器在编译时自动维护,而Lock是显式的,需要程序员手动实现lock()和unlock()方法。
14. 说一说synchronized的底层实现原理(⭐)
synchronized 是 Java 中用于实现线程同步的关键字,其底层实现原理与对象监视器息息相关。
在 Java 中,每个对象都有一个与之相关联的对象监视器,通过 synchronized 关键字来对对象加锁,实现线程同步,具体实现原理如下:
- 当线程进入 synchronized 代码块时,会首先尝试获取对象的对象监视器(锁)
- 如果该对象未被其他线程占用,则该线程会立即获得对象的对象监视器(锁),并标识该对象已经被该线程占用
- 如果该对象已经被其他线程占用,则该线程将进入等待状态,直到该对象被释放。
- 当该线程完成 synchronized 代码块中的任务后,会自动释放对象的对象监视器(锁)
- 其他线程可以继续获取该对象的对象监视器(锁),并继续执行 synchronized 代码块中的任务。
需要注意的是,synchronized 代码块只能保证同一时刻只有一个线程可以进入该代码块,但不能保证线程间的执行顺序和互斥性。如果需要保证线程间的执行顺序和互斥性,还需要结合使用 synchronized 关键字和 wait/notify/notifyAll 方法来实现。