文章目录
字符串对象的改变对象属性的改变
注意一个问题如果多个线程同时持有锁对象, 且同时持有的是相同的锁对象, 那么这些线程之间的任务就是同步的, 如果分别持有不同的锁对象, 那么就是异步的.
字符串对象的改变
任务代码
public class MyService {
private String lock
= "123";
public void testMethod() {
synchronized (lock
) {
System
.out
.println(Thread
.currentThread().getName() + " begin at: "
+ System
.currentTimeMillis());
lock
= "456";
try {
Thread
.sleep(2000);
} catch (InterruptedException e
) {
e
.printStackTrace();
}
System
.out
.println(Thread
.currentThread().getName() + " end at: "
+ System
.currentTimeMillis());
}
}
}
线程类和启动类
public class Run2 {
public static void main(String
[] args
) throws InterruptedException
{
MyService service
= new MyService();
Thread t1
= new Thread("A") {
@Override
public void run() {
service
.testMethod();
}
};
Thread t2
= new Thread("B") {
@Override
public void run() {
service
.testMethod();
}
};
t1
.start();
Thread
.sleep(100);
t2
.start();
}
}
运行结果 此时我们发现A和B俩个线程是A获得锁进入之后过了100秒后B也获得锁进入了, 但是此时A并没有出去, 也就是A并没有释放锁, 究其原因就是A进入之后再0.1秒内修改了lock这个对象, 要知道字符串类型"123"和"456"是俩个不同的类型, 所以才会有这样的现象, 如果我们不让等待那0.1秒, 就不会出现这样的问题 注释掉后就不会有这样的问题 此时A和B差不多是同时要求启动, 俩个线程之间一开始竞争的还是"123"这把锁, 虽然将锁改成"456" , 但结果还是异步的, 因为共同争抢的锁是"123"
对象属性的改变
user类
public class User {
public String name
;
public int age
;
public User(String name
, int age
) {
this.name
= name
;
this.age
= age
;
}
}
服务类
public class Service {
public void testMethod(User user
) {
synchronized (user
) {
System
.out
.println(Thread
.currentThread().getName() + " begin: " +
System
.currentTimeMillis());
user
.age
= 99;
user
.name
= "HaHa";
try {
Thread
.sleep(3000);
} catch (InterruptedException e
) {
e
.printStackTrace();
}
System
.out
.println(Thread
.currentThread().getName() + " end: " +
System
.currentTimeMillis());
}
}
}
启动类
public class Run3 {
public static void main(String
[] args
) throws InterruptedException
{
User user
= new User("listen", 20);
Service service
= new Service();
Thread t1
= new Thread("A") {
@Override
public void run() {
service
.testMethod(user
);
}
};
Thread t2
= new Thread("B") {
@Override
public void run() {
service
.testMethod(user
);
}
};
t1
.start();
Thread
.sleep(100);
t2
.start();
}
}
运行结果 这个代码我们发现, 只要对象不变, 即使属性被改变, 运行的结果还是同步的