2.2.8细化3个结论
synchronized(非this对象x)格式的写法是将x对象本身作为“对象监视器”,这样就有以下3个结论:
1)当多个线程同时执行synchronized(x){}同步代码块是呈同步效果。
2)当其他线程执行x对象中synchronized同步方法是呈同步效果。
3)当其他线程执行x对象方法里面的synchronized(this)代码块时也是呈现同步效果。
但需要注意:如果其他线程调用不加synchronized关键字的方法时,还是异步调用。
2.2.9静态同步synchronized方法与synchronized(class)代码块
synchronized关键字加到static静态方法上是给Class类上锁,而synchronized关键字加到非static静态方法上是给对象上锁。
2.2.10数据类型String的常量池特性
将synchronized(string)同步块与string联合使用时,要注意常量池以带来的一些例外。
常量池不变,是一个对象。
因此大多数情况下,同步synchronized代码块都不使用String作为锁对象,而改用其他,比如new Object()实例化一个Object对象,但它并不放入缓存中。
2.2.11同步synchronized方法无限等待与解决
同步方法容易造成死循环,这时候讲同步方法修改为同步代码块可解决。
2.2.12多线程的死锁
多线程死锁是一个经典的多线程问题。
因为不同的线程都在等待根本不可能被释放的锁,从而导致索引的任务都无法继续完成。
在多线程中,“死锁”是必须避免的,因为这会造成线程“假死”。
死锁是程序设计的bug,在设计程序时就要避免双方互相持有对方的锁的情况。
2.1.13内置类和静态内置类
两种情况:
1)在内置类中有两个同步方法,但使用的却是不同的锁,打印的结果也是异步的
2)同步代码块synchronized(class2)对class2上锁后,其他线程只能以同步的方式调用class2中的静态同步方法。
2.1.16锁对象的改变
在将任何数据类型作为同步锁时,需要注意的是,是否有多个线程同时持有锁对象,如果同时持有相同的锁对象,则这些线程之间就是同步的;
如果分别获得锁对象,这些线程之间就是异步的。
ps:只要对象不变,即使对象的属性被改变,运行的结果还是同步的。
\