在将任何数据类型作为同步锁时,需要注意的是,是否有多个线程同时持有锁对象,如果同时持有相同的锁对象,
则这些线程之间就是同步的;如果分别获得锁对象,这些线程直接就是异步的
1. 数值型数据
直接看例子,然后再解释:
public class MyService {
private String lock="123";
public void testMethod(){
try {
synchronized (lock){
System.out.println(Thread.currentThread().getName()+" begin "+System.currentTimeMillis());
Thread.sleep(50);
lock="456";
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName()+" end "+System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadA extends Thread{
private MyService myService;
public ThreadA(MyService myService){
super();
this.myService=myService;
}
@Override
public void run() {
myService.testMethod();
}
}
* 情况1:
public class Run1 {
public static void main(String[] args) throws InterruptedException{
MyService service=new MyService();
ThreadA a=new ThreadA(service);
a.setName("A");
ThreadA b=new ThreadA(service);
b.setName("B");
a.start();
Thread.sleep(100);
b.start();
}
}
结果:
A begin 1503113512171
B begin 1503113512275
A end 1503113514223
B end 1503113514341
*情况2:
public class Run1 {
public static void main(String[] args) throws InterruptedException{
MyService service=new MyService();
ThreadA a=new ThreadA(service);
a.setName("A");
ThreadA b=new ThreadA(service);
b.setName("B");
a.start();
b.start();
}
}
结果:
B begin 1503113404726
B end 1503113406794
A begin 1503113406794
A end 1503113408846
* 总结一下,如果线程已经在等待锁,如上面的B线程,那么该锁就不会再变化了,即使该对象本身确实发生了变化,
如果还没有加锁或者等待锁,则可以变化。
2. 引用型数据
只要对象不变,已经对象的属性被改变,运行的结果还是同步
eg:
public class Userinfo {
private String Username;
private String sex;
public String getUsername() {
return Username;
}
public void setUsername(String username) {
Username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
public class Service {
public void serviceMethodA(Userinfo userinfo){
synchronized (userinfo){
try {
System.out.println(Thread.currentThread().getName());
userinfo.setUsername("abcabsdfdf");
Thread.sleep(3000);
System.out.println("end! time="+System.currentTimeMillis());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
public class ThreadA extends Thread{
private Service service;
private Userinfo userinfo;
public ThreadA(Service service,Userinfo userinfo){
super();
this.service=service;
this.userinfo=userinfo;
}
@Override
public void run() {
service.serviceMethodA(userinfo);
}
}
public class Run {
public static void main(String[] args){
try{
Service service=new Service();
Userinfo userinfo=new Userinfo();
ThreadA a=new ThreadA(service,userinfo);
a.setName("a");
a.start();
Thread.sleep(50);
ThreadA b=new ThreadA(service,userinfo);
b.setName("b");
b.start();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
结果:
a
end! time=1503114681655
b
end! time=1503114684664
相关文章
- Java多线程之读写锁分离设计模式
- 多线程并发(二):聊聊AQS中的共享锁实现原理
- 【多线程与高并发】- synchronized锁的认知
- 微软出品自动化神器【Playwright+Java】系列(九)多线程、重定向、弹出新窗口、截图、新页面、录制、页面对象模式操作
- Java多线程并发编程/锁的理解
- Android进阶——多线程系列之wait、notify、sleep、join、yield、synchronized关键字、ReentrantLock锁
- Java多线程与并发应用-(6)-多个线程之间共享对象和数据的方式
- 黑马程序员 java 基础 毕向东 面向对象 多线程
- 【C/C++多线程编程之九】pthread读写锁
- 【Cocos2d-X开发学习笔记】第18期:动作类之改变动作对象、函数回调动作以及过程动作的使用