2.2.16锁对象的改变
Posted 成功的路上总是离不开贵人的帮助,名师的指点和小人的刺激。
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2.2.16锁对象的改变相关的知识,希望对你有一定的参考价值。
在将任何数据类型作为同步锁时,需要注意的是,是否有多个线程同时持有锁对象,如果同时持有相同的锁对象,则这些线程之间就是同步的,如果分别获得锁对象,这些线程之间是异步的。
package com.cky.thread; /** * Created by edison on 2017/12/9. */ public class MyServIce { private String lock ="123"; public void testMethodA (){ try { synchronized (lock) { System.out.println(Thread.currentThread().getName() + "begin="+System.currentTimeMillis()); lock="456"; Thread.sleep(2000); System.out.println(Thread.currentThread().getName() + "end="+System.currentTimeMillis()); } } catch (InterruptedException e) { e.printStackTrace(); } } }
package com.cky.thread; /** * Created by edison on 2017/12/8. */ public class ThreadA extends Thread{ private MyServIce service; public ThreadA(MyServIce service) { this.service = service; } @Override public void run() { super.run(); service.testMethodA(); } }
package com.cky.thread; /** * Created by edison on 2017/12/8. */ public class ThreadB extends Thread{ private MyServIce service; public ThreadB(MyServIce service) { this.service = service; } @Override public void run() { super.run(); service.testMethodA(); } }
package com.cky.thread; /** * Created by edison on 2017/12/9. */ public class Test2 { public static void main(String[] args) throws InterruptedException { MyServIce myServIce = new MyServIce(); ThreadA a = new ThreadA(myServIce); a.setName("A"); ThreadB b= new ThreadB(myServIce); b.setName("B"); a.start(); Thread.sleep(50); b.start(); } }
结果分析:
因为50毫秒过后线程B 获得的锁是456
继续测试:
去掉代码Thread.sleep(50)
package com.cky.thread; /** * Created by edison on 2017/12/9. */ public class Test2 { public static void main(String[] args) throws InterruptedException { MyServIce myServIce = new MyServIce(); ThreadA a = new ThreadA(myServIce); a.setName("A"); ThreadB b= new ThreadB(myServIce); b.setName("B"); a.start(); //Thread.sleep(50); b.start(); } }
Bbegin=1512803944419 Bend=1512803946419 Abegin=1512803946419 Aend=1512803948419
线程A和B持有的锁都是123,虽然将锁改成了456。但是结果还是同步的,因为线程A和B共同争抢的锁是123
注意:只要对象不变,即使对象的属性被改变,运行的结果还是同步的,测试如下
package com.cky.daemon; /** * Created by edison on 2017/12/9. */ public class Service { public void methodA(UserInfo userInfo) { synchronized (userInfo) { try { System.out.println("begin"+Thread.currentThread().getName()); userInfo.setUsrname("aaaa"); Thread.sleep(2000); System.out.println("end"+ System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } } }
package com.cky.daemon; /** * Created by edison on 2017/12/9. */ public class UserInfo { private String usrname; public String getUsrname() { return usrname; } public void setUsrname(String usrname) { this.usrname = usrname; } }
package com.cky.daemon; import com.cky.thread.ThreadA; import com.cky.thread.ThreadB; /** * Created by edison on 2017/12/9. */ public class Test { public static void main(String[] args) { try { Service service = new Service(); UserInfo userInfo = new UserInfo(); ThreadA threadA = new ThreadA(service, userInfo); threadA.setName("a"); threadA.start(); Thread.sleep(50); ThreadB threadB = new ThreadB(service, userInfo); threadB.setName("b"); threadB.start(); } catch (InterruptedException e) { e.printStackTrace(); } } }
package com.cky.thread; import com.cky.daemon.Service; import com.cky.daemon.UserInfo; /** * Created by edison on 2017/12/8. */ public class ThreadA extends Thread{ private Service service; private UserInfo userInfo; public ThreadA(Service service, UserInfo userInfo) { this.service = service; this.userInfo = userInfo; } @Override public void run() { super.run(); service.methodA(userInfo); } }
package com.cky.thread; import com.cky.daemon.Service; import com.cky.daemon.UserInfo; /** * Created by edison on 2017/12/8. */ public class ThreadB extends Thread{ private Service service; private UserInfo userInfo; public ThreadB(Service service, UserInfo userInfo) { this.service = service; this.userInfo = userInfo; } @Override public void run() { super.run(); service.methodA(userInfo); } }
begina
end1512804642120
beginb
end1512804644121
以上是关于2.2.16锁对象的改变的主要内容,如果未能解决你的问题,请参考以下文章