本人初学多线程,在关于多个线程访问多个对象的时候会产生多个锁问题有点疑问。
代码
public class HasSelfPrivateNum {
//num放在方法外面
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 (Exception e) {
e.printStackTrace();
}
}
}
下面是两个线程,线程A,线程B
public class ThreadA extends Thread {
private HasSelfPrivateNum numRef;
public ThreadA(HasSelfPrivateNum numRef) {
this.numRef = numRef;
}
@Override
public void run() {
numRef.addI("a");
}
}
public class ThreadB extends Thread {
private HasSelfPrivateNum numRef;
public ThreadB(HasSelfPrivateNum numRef) {
this.numRef = numRef;
}
@Override
public void run() {
numRef.addI("b");
}
}
测试类
public class Run {
public static void main(String[] args) {
/**
* 两个线程分别访问同一个类的不同实例的相同名称的同步方法 本类访问同步方法数据会按顺序打印结果
* 但实际效果确实异步形式,创建了同一个对象的两个不同实例numRef1,numRef2所以访问时两次访问了同步锁方法,所以运行结果是异步的
*/
/**
* synchronized取得的是对象锁,而不是把一段代码或方法当锁,
* 所以,哪个线程先执行带synchronized关键字的方法,哪个对象就持有该方法的锁,这里就是ThreadA先持有锁
* 那么其他线程(ThreadB)只能为等待状态。
* 当然这里有个前提:多个线程访问的是同一个对象,那这里就有两个对象(numRef1,numRef2)所以不符合这种情况
*/
HasSelfPrivateNum numRef1 = new HasSelfPrivateNum();
ThreadA athread = new ThreadA(numRef1);
athread.start();
HasSelfPrivateNum numRef2 = new HasSelfPrivateNum();
ThreadB bthread = new ThreadB(numRef2);
bthread.start();
}
}
按道理addI方法是加上了同步锁的,那访问这个方法的对象都是同步的。运行结果应该是同步的
a set over
a num=100
b set over
b num=200
那为什么这里实际运行结果还是异步的呢?望解答。
因为你两个线程操作的是两个对象。。。所以不存在同步的问题。
你需要让两个线程操作同一个的对象,并且加锁,这样才能实现你要的同步效果。