在將任何數(shù)據(jù)類型作為同步鎖時(shí),需要注意的是,是否有多個(gè)線程同時(shí)持有鎖對(duì)象,如果同時(shí)持有相同的鎖對(duì)象,則這些線程之間就是同步的;如果分別獲得鎖對(duì)象,這些線程之間就是異步的。
/**
* @author wuyoushan
* @date 2017/4/19.
*/
public class MyService {
private String lock="123";
public void testMethod(){
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();
}
}
}
/**
* @author wuyoushan
* @date 2017/4/4.
*/
public class ThreadA extends Thread{
private MyService service;
public ThreadA(MyService service) {
this.service = service;
}
@Override
public void run() {
super.run();
service.testMethod();
}
}
/**
* @author wuyoushan
* @date 2017/4/4.
*/
public class ThreadB extends Thread{
private MyService service;
public ThreadB(MyService service) {
this.service = service;
}
@Override
public void run() {
super.run();
service.testMethod();
}
}
/**
* @author wuyoushan
* @date 2017/3/20.
*/
public class Run {
public static void main(String[] args) throws InterruptedException {
MyService service=new MyService();
ThreadA a=new ThreadA(service);
a.setName("A");
ThreadB b=new ThreadB(service);
b.setName("B");
a.start();
Thread.sleep(50);
b.start();
}
}
程序運(yùn)行后的結(jié)果為:
A begin 1493684592096
B begin 1493684592146
A end 1493684594096
B end 1493684594146
程序的結(jié)果是異步輸出的。因?yàn)?0毫秒過后B取得的鎖是“456”
/**
* @author wuyoushan
* @date 2017/3/20.
*/
public class Run {
public static void main(String[] args) throws InterruptedException {
MyService service=new MyService();
ThreadA a=new ThreadA(service);
a.setName("A");
ThreadB b=new ThreadB(service);
b.setName("B");
a.start();
// Thread.sleep(50);
b.start();
}
}
去掉Thread.sleep(50),程序的運(yùn)行結(jié)果如下:
A begin 1493685002103
A end 1493685004104
B begin 1493685004104
B end 1493685006104
線程A和B持有的鎖都是“123”,雖然將鎖改成了“456”,但是結(jié)果還是同步的,因?yàn)锳和B共同爭搶的鎖是“123”。
還需要提示一下,只要對(duì)象不變,即使對(duì)象的屬性被改變,運(yùn)行的結(jié)果還是同步。
/**
* @author wuyoushan
* @date 2017/4/10.
*/
public class Service {
public void serviceMethodA(UserInfo userInfo){
synchronized (userInfo){
try {
System.out.println(Thread.currentThread().getName());
userInfo.setUserName("abcabcabc");
Thread.sleep(3000);
System.out.println("end! time="+System.currentTimeMillis());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
/**
* @author wuyoushan
* @date 2017/4/4.
*/
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() {
super.run();
service.serviceMethodA(userInfo);
}
}
/**
* @author wuyoushan
* @date 2017/4/4.
*/
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.serviceMethodA(userInfo);
}
}
/**
* @author wuyoushan
* @date 2017/3/20.
*/
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);
ThreadB b = new ThreadB(service, userInfo);
b.setName("b");
b.start();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
程序的運(yùn)行結(jié)果為:
a
end! time=1493685934399
b
end! time=1493685937399
摘選自 java多線程核心編程技術(shù)-2.2.16