上一篇博客中介绍了多个线程同时访问一个对象,产生一个对象锁,属于同步访问,现在介绍下如果是访问多个对象,会怎么执行那?
Demo:
HasSelfPrivateNum类:
public class HasSelfPrivateNum {
private int num=0;
synchronized public void addI(String username){
try{
if(username.equals("a")){
num=100;
System.out.println("a set over!");
Thread.sleep(2000);
}else{
num=200;
System.out.println("b set over!");
}
System.out.println(username+" num="+num);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
线程类ThreadA和ThreadB:
public class ThreadA extends Thread {
private HasSelfPrivateNum numRef;
public ThreadA (HasSelfPrivateNum numRef){
super();
this.numRef=numRef;
}
@Override
public void run(){
super.run();
numRef.addI("a");
}
}
public class ThreadB extends Thread {
private HasSelfPrivateNum numRef;
public ThreadB (HasSelfPrivateNum numRef){
super();
this.numRef=numRef;
}
@Override
public void run(){
super.run();
numRef.addI("b");
}
}
Run类,执行Main方法:
public class Run {
public static void main(String[] args){
HasSelfPrivateNum numRef1=new HasSelfPrivateNum();
HasSelfPrivateNum numRef2=new HasSelfPrivateNum();
ThreadA athread=new ThreadA(numRef1);
athread.start();
ThreadB bthread=new ThreadB(numRef2);
bthread.start();
}
}
运行结果:
a set over!
b set over!
b num=200
a num=100
例子是两个线程分别访问同一个类的两个不同实例的相同名称的同步方法,效果是以异步的方式运行的。原因是:示例创建了2个业务对象,在系统中产生了2个锁,所以运行结果是异步的,打印的效果是先打印了b,然后打印了a。
HasSelfPrivateNum.java中使用了synchronized关键字,但打印的顺序却不是同步的是交叉的,为什么?
解:
关键字 synchronized取得的锁是对象锁,而不是把一段代码或方法(函数)当做锁,如果多个线程访问的是多个对象,则JVM会创建多个锁,互不影响。
番外:
如果在静态方法上加synchronized关键字,表示锁定类级别的锁,独占class类,这时候多个线程访问的是相同的锁。