读书人

synchronized异常用法

发布时间: 2013-08-13 16:43:28 作者: rapoo

synchronized错误用法

? ? 翻起tomcat5的源码,看到standardServer.java中的addservice方法:

?

? ? public void addService(Service service) {

?

? ? ? ? service.setServer(this);

?

? ? ? ? synchronized (services) {

? ? ? ? ? ? Service results[] = new Service[services.length + 1];

? ? ? ? ? ? System.arraycopy(services, 0, results, 0, services.length);

? ? ? ? ? ? results[services.length] = service;

? ? ? ? ? ? services = results; ---此处会导致同步失效,因为改写了锁的对象,也就是锁指向的区域发生了改变

?

? ? ? ? ? ? if (initialized) {

? ? ? ? ? ? ? ? try {

? ? ? ? ? ? ? ? ? ? service.initialize();

? ? ? ? ? ? ? ? } catch (LifecycleException e) {

? ? ? ? ? ? ? ? ? ? e.printStackTrace(System.err);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

?

? ? ? ? ? ? if (started && (service instanceof Lifecycle)) {

? ? ? ? ? ? ? ? try {

? ? ? ? ? ? ? ? ? ? ((Lifecycle) service).start();

? ? ? ? ? ? ? ? } catch (LifecycleException e) {

? ? ? ? ? ? ? ? ? ? ;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

?

? ? ? ? ? ? // Report this property change to interested listeners

? ? ? ? ? ? support.firePropertyChange("service", null, service);

? ? ? ? }

?

? ? }

? ? 由于Thread.Sleep()不会失去拥有的对象锁,做个例子验证一下

? ? ? ? public class Test {

?

? ? ? ? private static Object lock = new Object();

? ? ? ? public static void main(String[] args) {

?

? ? ? ? new Thread(){

? ? ? ? ? ? ? ? public void run() {

? ? ? ? ? ? ? ? ? ? ? ?synchronized (lock) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?System.out.println("thread1-----enter");

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?lock = new Object() ; //更换锁的对象

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?try {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Thread.sleep(3000); //让线程2可以运行,看是否能进入代码块

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} catch (InterruptedException e) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?System.out.println("thread1-----exit");

? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ?}

? ? ? ? }.start();

? ? ? ? new Thread(){

? ? ? ? ? ? ? ? public void run() {

? ? ? ? ? ? ? ? ? ? ? try {

? ? ? ? ? ? ? ? ? ? ? ? ? ? Thread.sleep(1000);//让上面的线程1先进入同步代码块

? ? ? ? ? ? ? ? ? ? ? } catch (InterruptedException e) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? ? ? ? ? ? }?

? ? ? ? ? ? ? ? ? ? ? synchronized (lock) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println("thread2-----enter");

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println("thread2-----exit");

? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ?}

? ? ? ?}.start();

? ? }

}

输出的结果为

thread1-----enter

thread2-----enter

thread2-----exit

thread1-----exit

可见上面的同步失败,连写tomcat的大牛都出错,可见synchronized的坑还不少。

读书人网 >编程

热点推荐