synchronized的锁对象改变问题(转)
原文:https://www.jianshu.com/p/f6b3cc21f5d7
作者:跨界师
大家都知道synchronized是一个对象锁,所以当对象变化时,锁就会消失,就会没有同步效果。
请看下面的问题:
package Thread; /** * Created by zhangzheming on 2018/1/15. */ public class ChangeLock { private String lock = "lock"; private void method(){ synchronized (lock){ try { System.out.println("当前线程:"+Thread.currentThread().getName()+"开始"); lock = "lock modify"; System.out.println("当前线程:"+Thread.currentThread().getName()+"完成"); }catch (Exception e){ e.printStackTrace(); } } } public static void main(String[] args){ final ChangeLock locks = new ChangeLock(); Thread t1 = new Thread(new Runnable() { @Override public void run() { locks.method(); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { locks.method(); } }); t1.start(); t2.start(); } }
结果是两个线程是几乎是同时完成任务,为什么呢?
那是因为在进行method方法执行时,锁对象改变了,这样同步机制就消失,没有了同步效果,这样对于多线程操作时,便是每个线程对象都可以同时进行操作。
但是如果我们对class对象进行修改是否也会有上述情况呢?
答案是否定的。
package Thread; /** * Created by zhangzheming on 2018/1/15. */ public class ModifyLock { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public synchronized void changeAttribute(String name,int age){ try{ System.out.println("当前线程:"+Thread.currentThread().getName()+"开始"); this.setName(name); this.setAge(age); System.out.println("当前线程:"+Thread.currentThread().getName()+"修改对象内容为:"+this.getName()+","+this.getAge()); Thread.sleep(2000); System.out.println("当前线程:"+Thread.currentThread().getName()+"结束"); }catch (Exception e){ e.printStackTrace(); } } public static void main(String[] args){ final ModifyLock locks = new ModifyLock(); Thread t1 = new Thread(new Runnable() { @Override public void run() { locks.changeAttribute("zhangsan",34); } },"t1"); Thread t2 = new Thread(new Runnable() { @Override public void run() { locks.changeAttribute("lisi",345); } },"t2"); t1.start(); t2.start(); } }
所以对于类对象的属性进行修改,并不影响锁的效果!