1.Synchronized的本质是不让其他线程在同一对象上再加一把锁。
2.Synchronized使用范畴:
(1)修饰方法,使之成为被同步化区域的一员
protected synchronized void shutdown() {
this.interrupt();
}
(2)修饰某个程序代码块
synchronized(this) {
this.wait(); // wait indefinitely for a notification
}
(3)修饰对象,特别是容器类。容器类默认没有考虑线程安全问题,我们必须自行实现同步以确保共享数据在多线程存取下不会出错。例如:
synchronized(list){
list.add(...);
}
或者使用java.util.Collections提供的方法,来返回在存取数据时,会同步化的容器对象。需要注意的是,在使用Iterator遍历对象的时候,并没有保证线程安全,如有需要,我们还需要代码实现。
List list = Collections.synchronizedList(new ArrayList());
...
synchronized(list){
Iterator i = list.iterator();
while(i.hasNext()){
...
}
}
3.synchronized对性能的影响
同步化确保共享数据的同步,但当一个线程锁定同步化区域,其它线程等待它释放执行权时,会造成系统的延迟。在线程多的时候,必然造成一定的效率问题,必然大型网站多人联机时。
4.如果父类的方法加了Synchronized,子类重写方法必须也加Synchronized么?如果子类的方法重写时声明Synchronized并调用super,那么子类对象上到底有几把锁呢?会因为竞争产生死锁么?
子类重写方法可以加Synchronized也可以不加,这主要依赖于重进入机制。同一个线程在同一对象上还没释放之前加第二次锁是不会出问题的,这个锁其实根本就没有加,所以不会产生互斥。